ALU in Verilog: "Unable to bind wire/reg/memory" - verilog

I am trying to make a simple 32 bit ALU with an overflow flag, and then output the inputs and results of the ALU to the screen, but I encountered some problems with connecting the elements for the test bench. I got this error:
test_32bALU.v:15: error: Wrong number of ports. Expecting 4, got 5.
test_32bALU.v:33: error: Unable to bind wire/reg/memory
test_unit.overflow' inalu_test'
2 error(s) during elaboration.
I am just starting with Verilog and I have a basic idea of the syntax. I know I am not supposed to ask debugging questions, but this is my only hope. My professor or TA wouldn't respond to me requests for help. I would appreciate it if anyone here could help me point out my mistakes.
This is my 32bALU.v file:
module alu(
input signed[31:0] a,b,
input[3:0] opcode;
output signed[31:0] c;
output overflow;
);
reg signed[31:0] result;
assign c = result;
reg tmp;
parameter
add = 4'b0000,
sub = 4'b0110,
sla = 4'b0001,
srai = 4'b0011;
always #(a,b,opcode)
begin
case(opcode)
add:
begin
c = a + b;
end
endcase
end
always #(c)
begin
if (c[32:31] == (2'b11 | 2'b10)) // Overflow
begin
tmp = 1'b1;
assign overflow = tmp;
end
else begin
tmp = 1'b0;
assign overflow = tmp;
end
end
assign result = c[31:0];
endmodule
test_32bALU.v
`timescale 1ns/1ps
module alu_test;
// Inputs
reg[31:0] a,b;
reg[2:0] opcode;
// Outputs
wire[31:0] c;
//wire [1:0] zero;
wire [1:0] overflow;
//wire [1:0] neg;
alu test_unit(
a,b, // Inputs
opcode,
c,
overflow
);
parameter
add = 4'b0000,
sub = 4'b0110,
sla = 4'b0001,
srai = 4'b0011;
initial begin
$display("op: a : b : c : reg_A : reg_B : reg_C");
$monitor(" %h:%h:%h:%h:%h:%h:%h",
opcode, a, b, c, test_unit.a, test_unit.b, test_unit.c);
$monitor("%h", test_unit.overflow);
//// add
#10 a=32'b0000_0000_0000_0000_0000_0000_0000_0001;
#10 b=32'b0000_0000_0000_0000_0000_0000_0000_0001;
opcode= add;//3'b000
#10 $finish;
end
endmodule
I am confused as to why it says "wrong number of ports"? I assume it's the number of parameters in module alu and alu test_unit? They have the same number of parameters (a, b, c, opcode and overflow), so what exactly am I missing? How exactly do I get the value of overflow? It works fine before I added the overflow parameter, so I assume I'm doing it wrong?
For the second error, I read somewhere on here that it might be due to a missing declaration, but I have declared all of them... so I am not sure what's making it wrong.

I am not sure if this is the issue, but your module definition is not correct. It should be as follows:
module alu(
input signed[31:0] a,b,
input[3:0] opcode,
output signed[31:0] c,
output overflow
);
Perhaps this may help with your issue.

Commas separate inputs and outputs in the module declaration.
NEVER rely on the order of arguments to modules and ALWAYS try to use, for a module called A;
module A(output wire c,
input wire a,
input wire b);
...
endmodule // A
use an instance of it using;
A yourAname(.c(Bar),
.a(Foo1),
.b(Foo2));
so that if the definition and order of the I/O of the module changes, this instantiation will track those changes and/or give appropriate errors when simulated/synethesised.
You might find it useful to follow a few simple rules in your source code when naming;
inputs are denoted by i_yourinputname
outputs are denoted by o_youroutputname
inout are denoted by io_yourinputoutputname
wire are denoted by w_yourwirename
reg are denoted by r_yourregname
as this avoid confusion and is a good habit to get into as soon as possible when starting to learn verilog.

Related

How to get MAX or MIN in Verilog?

I want to build a simple module to compare two 2-bit numbers and get the maximum number in the output.
I've used the code posted here: How to find MAX or MIN in Verilog coding?
module max (input [1:0] a,
input [1:0] b,
output reg [1:0] out);
always #* begin
if (a>b)
out = a;
else
out = b;
end
endmodule
But the problem I have, is that the output "out" does not give me a 2-bit number, and also the code is not working well as you can see in the screenshot.
This is the testbench I'm using:
`timescale 1ns/10ps
module maxTB();
reg [1:0] a, b;
max dut (.a(a),.b(b),.out(out));
initial
begin
a = 2'b1; b= 2'b0;
#20 a = 2'b10;
#40 b = 2'b11;
#50 a = 2'b01;
end
endmodule
modelsim screenshot
You haven't declared out in your TB, so it has defaulted to a 1-bit net (a wire). This is a rather major failing in the language. To turn this behaviour off, add this outside any module:
`default_nettype none

Input Output for 8-bit ALU using FPGA board

I am a newbie to xilinx so please excuse any stupidities in the code.
Ah so I am trying to design an 8-bit ALU and the module is working perfectly on the simulation but we need to take inputs and display outputs on FPGA board.
Technically I should have used RS-232 but since we just have an 8-bit input and 8 switches are available, we are trying to code it this way.
However, the code does not compile and gives error
"expecting 'endmodule', found 'forever'".
I used 'forever' and not 'always' because always does not allow any instance to be instantiated within it.
Can anybody please help us figure out what is wrong with the code?
module main(out,in,switch);
output [7:0] out;
input [7:0] in;
input switch;
reg [7:0] a,b,select;
reg [1:0] count;
wire eq, comp, C8;
initial
begin
count = 2'b00;
select = 8'b0000_0000;
end
MyALU A(eq, comp, C8, out, a, b, 1'b0, select[0], select[1], select[2], select[3]);
forever
begin
if (switch)
begin
case (count)
00:
begin
a = in;
count = 2'b01;
end
01:
begin
b = in;
count = 2'b10;
end
10:
begin
select = in;
A(eq, comp, C8, out, a, b, 1'b0, select[0], select[1], select[2], select[3]);
count = 2'b00;
end
default
a = in;
endcase
end
end
Every module in verilog must end with the line endmodule. That is missing in your code. And try using always#(*) instead of forever. forever is not synthesizable and only used for verification with simulation.
Replace the forever statement by always #(*).
Remove this line from the case statement:
A(eq, comp, C8, out, a, b, 1'b0, select[0], select[1], select[2], select[3]);
Add endmodule at the end.

Four Bit Adder Understanding

Can someone explain to me what I am doing wrong. I don't know if I just don't understand the concept or what. I have looked at two solid examples, both of which provide thorough code but maybe I am wiring things wrong or something.
1st - I have created an file called Adder and below is my code. This works completely fine, I have created/ran a test bench file with this so I know this does exactly what is intended. However, am I supposed to somehow connect my FullAdder file or the test bench for the FullAdder file to the Adder file? Are these completely separate files and are never connected?
module Adder (a,b,ci,co,s);
input a,b,ci;
output co,s;
assign s=a^b^ci;
assign co=(a&b)|(a&ci)|(b&ci);
endmodule
2nd - Below is my code for the FullAdder file. I am not sure if this is correct but let me know where I can make possible changes. I assume the test bench I create will be linked to this FullAdder file? The syntax for this file checks out alright, so maybe it is the test bench that is causing problems for me...
module FullAdder(a,b,ci,s);
input [3:0] a,b;
input ci;
output [3:0] s;
wire [2:0] co; // Is the wire correct here? I created this off something I saw.
Adder ADD1(a[0],b[0],ci,s[0],co[0]);
Adder ADD2(a[1],b[1],co[0],s[1],co[1]);
Adder ADD3(a[2],b[2],co[1],s[2],co[2]);
Adder ADD4(a[3],b[3],co[2],s[3],s[4]);
endmodule
3rd - I don't understand the test bench and wiring everything all together. I have looked at these two links which have two different ways of doing this.
Link 1 Link 2. I have tried to replicate link 2, but can't seem to get it working. Help?
Adder ADD4(a[3],b[3],carry[2],s[3],s[4]);
This instantiation assumes that s is a vector with an element in position 4, but your definition of s is [3:0] so 4 is not a valid position. Change it to
output [4:0] s;
It's desiderabel to use the Verilog 2001 module definition style (resembles ANSI C). Your module would be like this:
module FullAdder (
input wire [3:0] a,
input wire [3:0] b,
input wire ci,
output wire [4:0] s
);
wire [2:0] co;
Adder ADD1(a[0],b[0],ci,s[0],co[0]);
Adder ADD2(a[1],b[1],co[0],s[1],co[1]);
Adder ADD3(a[2],b[2],co[1],s[2],co[2]);
Adder ADD4(a[3],b[3],co[2],s[3],s[4]);
endmodule
Regarding your test bench (link 2) you mispelled some names: the name of 1-bit address is called "adder", not "Adder". Change either the definition or the instance name. The name of the ports are a,b,cin and s, not p,q,ci and r. These last are the signals (wires) you will connect to your ports.
As this adder has a limited set of inputs, I'd suggest to do an exhaustive test bench. So instead of probing two sample values for a,b and cin, try all the posibilities, and check that the result is the expected one. Something like this:
// Code your testbench here
module test_bench;
// Inputs
reg [3:0] p;
reg [3:0] q;
reg ci;
// Outputs
wire [4:0] r;
// Instantiate the Unit Under Test (UUT)
FullAdder uut (
.a(p),
.b(q),
.ci(ci),
.s(r)
);
initial begin
ci = 1'b0;
repeat (2) begin
p = 4'b0000;
repeat (16) begin
q = 4'b0000;
repeat (16) begin
#10;
$display ("%b + %b + %b = %b", p, q, ci, r);
if (r != (p+q+ci)) begin
$display ("ERROR!. Expected %b", p+q+ci);
$finish;
end
#10;
q = q + 1;
end
#10;
p = p + 1;
end
#10;
ci = !ci;
end
$display ("EVERYTHING OK!");
$finish;
end
endmodule
See http://www.edaplayground.com/x/HR5

6-bit Full Adder returns with an error [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
module adder6(
output[5:0] sum,
output c_out,
input[5:0] a, b,
input c_in);
wire [1:0] c_o;
adder4 a(.sum([3:0]),c_o[0],.a(a[3:0]), .b(b[3:0),c_in); //4-bits adder
full_adder fa1(sum[4],c_o[1],a[4],b[4],c_o[0]); //1-bit adder
full_adder fa2(sum[5],c_out,a[5],b[5],c_o[1]); //1-bit adder
endmodule
module adder4(
output[3:0] sum,
output c_out, // carry out
input[3:0] a, b, // operands
input c_in); // carry in
wire [2:0] c_o;
full_adder fa1(sum[0],c_o[0],a[0],b[0],c_in);
full_adder fa2(sum[1],c_o[1],a[1],b[1],c_o[0]);
full_adder fa3(sum[2],c_o[2],a[2],b[2],c_o[1]);
full_adder fa4(sum[3],c_out,a[3],b[3],c_o[2]);
endmodule
module full_adder(
output sum,
output c_out, // carry out
input a,
input b,
input c_in); // carry in
wire sum1;
wire c_in1;
wire c_out2;
half_adder ha1(sum1,c_in1,a,b);
half_adder ha2(sum,c_out2,sum1,c_in);
or(c_out,c_out2,c_in1);
endmodule
module half_adder(
output sum,
output c_out, // carry out
input a,
input b);
assign sum=a^b;
assign c_out=a&&b;
endmodule
I have to make a 6-bit adder from an 4-bit adder and two full-adders. I am sure that the problem is within the adder6 module since I have already tested the 4-bit adder module separately, and it works. But I cannot find the mistake. I am not sure if I made the correct connections in the adder4 function that I have used in adder6 module.
(Update 1):
module adder6_test;
// Inputs
reg [5:0] a;
reg [5:0] b;
// Outputs
wire [6:0] sum;
// Instantiate the Unit Under Test (UUT)
adder6 uut (
.sum(sum),
.a(a),
.b(b)
);
initial begin
// Initialize Inputs
a = 0;
b = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
a = 50;
b = 14;
#10;
a = 2;
b = 33;
#10;
a = 63;
b = 63;
end
endmodule
(Update 2):
The error is:
ERROR:HDLCompiler:806 - "C:/Users/Iulia/Downloads/lab1_skel/ex4_skel/adder6.v" Line 10: Syntax error near ")".
// Verilog Test Fixture Template
`timescale 1 ns / 1 ps
module TEST_gate;
reg <signal1>;
reg [2:0] <signal2>;
wire [3:0] <signal3>;
wire <signal4>;
<module_name> <instance_name> (
<port1>,
<port2>
);
integer <name1>;
integer <name2>;
// The following code initializes the Global Set Reset (GSR) and Global Three-State (GTS) nets
// Refer to the Synthesis and Simulation Design Guide for more information on this process
reg GSR;
assign glbl.GSR = GSR;
reg GTS;
assign glbl.GTS = GTS;
initial begin
GSR = 1;
GTS = 0; // GTS is not activated by default
#100; // GSR is set for 100 ns
GSR = 0;
end
// Initialize Inputs
`define auto_init
`ifdef auto_init
initial begin
end
`endif
endmodule
Now I get these errors:
ERROR:HDLCompiler:806 - "C:/Users/Iulia/Downloads/lab1_skel/ex4_skel/adder6_test.v" Line 6: Syntax error near "<".
ERROR:HDLCompiler:806 - "C:/Users/Iulia/Downloads/lab1_skel/ex4_skel/adder6_test.v" Line 7: Syntax error near "<".
ERROR:HDLCompiler:806 - "C:/Users/Iulia/Downloads/lab1_skel/ex4_skel/adder6_test.v" Line 8: Syntax error near "<".
(Update 3) I modified the adder6 module and I managed to get rid of the errors. I used a 7-bit sum, and I've eliminated the carry in. But now, it doesn't calculate the sum. For a=63 and b=63 the sum is X. This is the new adder6 module:
module adder6(
output[6:0] sum,
input[5:0] a,
input[5:0] b);
wire c_out0;
wire c_out1;
adder4 add4(sum[3:0],c_out0,a[3:0],b[3:0],c_in);
full_adder fa3(sum[4],c_out1,a[4],b[4],c_out0);
full_adder fa4(sum[5],sum[6],a[5],b[5],c_out1);
endmodule
In your adder6 declaration have this line:
adder4 a(.sum([3:0]),c_o[0],.a(a[3:0]), .b(b[3:0),c_in); //4-bits adder
As you can see, you've called an instance of adder4 a. At the same time, you've called an input port a. That's why you're getting an error when trying to compile your code. The easiest solution would be to rename an adder4 instance.
Btw that particular line should look a little bit different in case to work:
adder4 add(.sum(sum[3:0]), .c_out(c_o[0]), .a(a[3:0]), .b(b[3:0]), .c_in(c_in));

Two's complement in verilog

I've been trying to build a module which returns the two's complement representation of the (3-bit) input (first bit being the sign). I think that the following code is correct conceptually, but I am probably missing something about it's structure: when I try to compile, I get the following errors:
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
(vlog-2110) Illegal reference to net "f_o".
Searching for that error showed it is usually seen when using a variable as input and output at the same time, but that's not my case. Could you point where the error is?
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
always #(a_i[2:0] or f_o[2:0])
begin
if (a_i[2] == 1)
begin
f_o[2] = a_i[2];
f_o[1:0] = (~a_i[1:0] + 'b1);
end
else
begin
f_o = a_i;
end
end
endmodule
In Verilog, undeclared identifiers are considered implicit wire declarations in most circumstances. Since f_o has not been declared the compiler considers it a wire, not a variable. This causes the compiler to complain about all the assignments.
// What was typed
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
// What the compiler implicitly declares
wire [2:0] a_i;
wire [2:0] f_o;
To fix it you can declare the variable or declare both the port and the variable.
module ca2 (a_i,f_o);
input [2:0] a_i;
output [2:0] f_o;
reg [2:0] f_o;
module ca2 (a_i,f_o);
input [2:0] a_i;
output reg [2:0] f_o;
f_o needs to be declared as a reg. output reg [2:0] f_o.
Also I am not sure what you are calculating, that is not a standard twos complement.
module ca2 (
input [2:0] a_i,
output [2:0] twos_comp,
output [2:0] also_twos_comp
);
assign twos_comp = ~a_i + 1'b1;
assign also_twos_comp = -a_i ;
endmodule
You may be dealing with an encoded input, but twos_complement is to negate the number I would expect the sign bit (MSB) to change. Although we refer to it as a sign bit it also contains information about the value and therefore can not just be stripped off and leave the number unchanged.
The first solution -> In sequential circuits, the output must be in the form of a reg.
and Next we need to know that in two's complement we start from bit zero to get to the end so the condition is incorrect.
If the zero bit is one, then the zero bit is unchanged and the rest of the bits change to not.
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
always #(a_i[2:0] or f_o[2:0]) begin
if (a_i[0] == 1'b1) begin
f_o[0] = a_i[0];
f_o[2:1] = (~a_i[2:1]);
end
else
if(a_i[1]==1'b1) begin
f_o[1:0] = a_i[1:0];
f_o[2] = (~a_i[2]);
end
else
if(a_i[2] == 1'b1) begin
f_o = a_i ;
end
end
endmodule
The second solution -> In binary numbers, if we subtract the number from zero, we get two's complement .
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
always #(a_i[2:0] or f_o[2:0]) begin
f_o = 3'b000 - a_i ;
end
endmodule
The third solution -> all bits change to not and Finally, they are added to the number one (3'b000 = 3'b0)
module ca2 (input [2:0] a_i,output reg [2:0] f_o);
reg [2:0] finish ;
always #(a_i[2:0] or f_o[2:0]) begin
finish = (~a_i);
f_o = finish + 3'b001 ;
end
endmodule

Resources