verilog error ... (vlog-2110) Illegal reference to net array - verilog

Using Verilog, I want to make 4by4 multiplier, but there is one error:
vlog-2110) Illegal reference to net array "w11".
about other variables w12, o1..... there is also error...
I cannot understand the meaning of the error. If you can solve this error, please tell me.
module half_adder (x,y,s,c);
input x,y;
output s,c;
assign s=x^y;
assign c=x&y;
endmodule
module full_adder (x,y,z,s,c);
input x,y,z;
output s,c;
wire w1,w2,w3;
half_adder h1(x,y,w1,w2);
half_adder h2(w1,z,s,w3);
assign c = w2|w3;
endmodule
module four_bit_adder (a, b, c0, s, c4);
input [3:0]a;
input [3:0]b;
input c0;
output [3:0]s;
output c4;
wire c1,c2,c3;
full_adder fu1(a[0],b[0],c0,s[0],c1);
full_adder fu2(a[1],b[1],c1,s[1],c2);
full_adder fu3(a[2],b[2],c2,s[2],c3);
full_adder fu4(a[3],b[3],c3,s[3],c4);
endmodule
maybe there is error next code
// 4by4_multiplier
module four_four_multi (A,B, zero, C);
input [3:0]A;
input [3:0]B;
input zero;
output [7:0]C;
wire w11[3:0];
wire w12[3:0];
wire o1[3:0];
wire w21[3:0];
wire w22[3:0];
wire o2[3:0];
wire w31[3:0];
wire w32[3:0];
wire o3[3:0];
wire o4;
assign C[0] = A[0] & B[0];
assign w11[0] = A[0] & B[1];
assign w11[1] = A[0] & B[2];
assign w11[2] = A[0] & B[3];
assign w11[3] = 0;
assign w12[0] = A[1] & B[0];
assign w12[1] = A[1] & B[1];
assign w12[2] = A[1] & B[2];
assign w12[3] = A[1] & B[3];
four_bit_adder four1(w11, w12, zero, o1 ,w21[3] );
assign C[1] = o1[0];
assign w21[0] = o1[1];
assign w21[1] = o1[2];
assign w21[2] = o1[3];
assign w22[0] = A[2] & B[0];
assign w22[1] = A[2] & B[1];
assign w22[2] = A[2] & B[2];
assign w22[3] = A[2] & B[3];
four_bit_adder four2(w21, w22, zero, o2 ,w31[3] );
assign C[2] = o2[0];
assign w31[0] = o2[1];
assign w31[1] = o2[2];
assign w31[2] = o2[3];
four_bit_adder four3(w31, w32, zero, o3 , o4 );
assign C[3] = o3[0];
assign C[4] = o3[1];
assign C[5] = o3[2];
assign C[6] = o3[3];
endmodule

The following declaration declares nets w11, w12, ... as arrays of nets.
wire w11[3:0];
wire w12[3:0];
...
The verilog standard allows you to declare them but does not allow using them as whole array in ports. To fix it in verilog you need to declare those nets as vectors:
wire [3:0] w11;
wire [3:0] w12;
...
System Verilog relaxed this rule and it should work in that language as is.

Related

For instance uut/A1/, width 1 of formal port S is not equal to width 4 of actual signal in1

Can anyone tell why I am getting these warnings?
For instance uut/A1/, width 1 of formal port S is not equal to width 4
of actual signal in1.
For instance uut/A1/, width 1 of formal port Cout is not equal to
width 4 of actual signal in2.
For instance uut/A1/, width 1 of formal port A is not equal to width 4
of actual signal s1.
For instance uut/A2/, width 1 of formal port S is not equal to width 4
of actual signal in3.
For instance uut/A2/, width 1 of formal port Cout is not equal to
width 4 of actual signal in4.
For instance uut/A2/, width 1 of formal port A is not equal to width 4
of actual signal s2.
module binary(A,B,P);
input [2:0]A;
input [3:0]B;
output [6:0]P;
wire c1,c2;
wire [3:0]s1,in1,in2,in3,in4,s2;
assign in1[0] = A[0] & B[1];
assign in1[1] = A[0] & B[2];
assign in1[2] = A[0] & B[3];
assign in2[0] = A[1] & B[0];
assign in2[1] = A[1] & B[1];
assign in2[2] = A[1] & B[2];
assign in2[3] = A[1] & B[3];
assign in3[0] = A[2] & B[0];
assign in3[1] = A[2] & B[1];
assign in3[2] = A[2] & B[2];
assign in3[3] = A[2] & B[3];
FA A1(in1,in2,s1,c1);
assign in4[0] = s1[1];
assign in4[1] = s1[2];
assign in4[2] = s1[3];
assign in4[3] = c1;
FA A2(in3,in4,s2,c2);
assign P[0] = A[0] & B[0];
assign P[1] = s1[0];
assign P[2] = s2[0];
assign P[3] = s2[1];
assign P[4] = s2[2];
assign P[5] = s2[3];
assign P[6] = c2;
endmodule
module FA(S, Cout, A, B, Cin);
output S;
output Cout;
input A;
input B;
input Cin;
wire w1;
wire w2;
wire w3;
wire w4;
xor(w1, A, B);
xor(S, Cin, w1);
and(w2, A, B);
and(w3, A, Cin);
and(w4, B, Cin);
or(Cout, w2, w3, w4);
endmodule
You declared the S output port of the FA module as a 1-bit signal:
module FA(S, Cout, A, B, Cin);
output S;
Inside module binary, you declared in1 as a 4-bit signal:
wire [3:0]s1,in1,
Then you connected a 4-bit signal (in1) to a 1-bit port (S):
// S
FA A1(in1,in2,s1,c1);
Since this is an unusual thing to do, your tool is doing the correct thing by issuing a warning message.
The width of the signal should match the width of the port. Based on your design requirements, you must decide which bit of in1 to connect to S. For example,
FA A1(in1[0],in2,s1,c1);
The same applies for the other warnings as well.

Verilog 4-bit comparator structural model

I would like to design a 4-bit comparator as a structural model using a 2-bit comparator.
As shown in the attached picture, after giving initial values ​​to each of Gt_I, Eq_I, and Lt_I, you need to design a 4-bit comparator as a structural model of a 2-bit comparator.
The code I've tried is a syntax error in assigning the initial values ​​of Gt_I, Eq_I, and Lt_I. I want to know a solution.
<2bit>
module Comparator_new(a, b, Gt_I, Eq_I, Lt_I, Gt_O, Eq_O, Lt_O);
input [1:0] a;
input [1:0] b;
input Gt_I, Eq_I, Lt_I;
output Gt_O, Eq_O, Lt_O;
assign Gt_O = ~(a[1] & ~b[1] | ~a[1] & b[1]) & a[0] & ~b[0] | a[1] & ~b[1];
assign Eq_O = ~(a[0] & ~b[0] | ~a[0] & b[0]) & ~(a[1] & ~b[1] | ~a[1] & b[1]);
assign Lt_O = ~(a[1] & ~b[1] | ~a[1] & b[1]) & ~a[0] & b[0] | ~a[1] & b[1];
endmodule
<4bit>
module Comparator_stru(a, b, Gt_I, Eq_I, Lt_I, Gt, Eq, Lt);
input [3:0] a;
input [3:0] b;
input Gt_I = 2'b00;
input Eq_I = 2'b01;
input Lt_I = 2'b00;
output Gt, Eq, Lt;
wire x, y, z;
Comparator_new c0(.a(a), .b(b), .Gt_I(Gt_I), .Eq_I(Eq_I), .Lt_I(Lt_I), .Gt_O(x), .Eq_O(y), .Lt_O(z));
Comparator_new c1(.a(a), .b(b), .Gt_I(x), .Eq_I(y), .Lt_I(z), .Gt_O(Gt), .Eq_O(Eq), .Lt_O(Lt));
assign Gt_O = ~(a[3] & ~b[3] | ~a[3] & b[3]) & a[2] & ~b[2] | a[3] & ~b[3];
assign Eq_O = ~(a[2] & ~b[2] | ~a[2] & b[2]) & ~(a[3] & ~b[3] | ~a[3] & b[3]);
assign Lt_O = ~(a[3] & ~b[3] | ~a[3] & b[3]) & ~a[2] & b[2] | ~a[3] & b[3];
endmodule
`timescale 1ns/10ps
module tb_Comparator_stru;
reg a, b;
wire Gt, Eq, Lt;
Comparator_stru tb(.a(a), .b(b), .Gt(Gt), .Eq(Eq), .Lt(Lt));
initial
begin
$dumpfile("test_Comparator_stru_out.vcd");
$dumpvars(-1, tb);
$monitor("%b", Gt);
$monitor("%b", Eq);
$monitor("%b", Lt);
end
initial
begin
a = 2'b00; b = 2'b00;
#50 a = 2'b01; b = 2'b00;
#50 a = 2'b01; b = 2'b01;
#50 a = 2'b01; b = 2'b10;
#50 a = 2'b10; b = 2'b10;
#50 a = 2'b11; b = 2'b10;
#50 a = 2'b11; b = 2'b11;
#50;
end
endmodule
Gt_I, Eq_I, and Lt_I are input ports of module Comparator_stru. They are driven by, and receive values from their drivers.
In your case, if you want to assign initial values to them, you need to use initial block, and do it in the testbench.
<4bit>
module Comparator_stru(a, b, Gt_I, Eq_I, Lt_I, Gt, Eq, Lt);
input [3:0] a;
input [3:0] b;
input Gt_I; // = 2'b00;
input Eq_I; // = 2'b01;
input Lt_I; // = 2'b00;
testbench
Comparator_stru tb(.a(a), .b(b), .Gt_I(Gt_I), .Eq_I(Eq_I), .Lt_I(Lt_I), .Gt(Gt), .Eq(Eq), .Lt(Lt));
initial begin
Gt_I = 1'b0;
Eq_I = 1'b1;
Lt_I = 1'b0;
end
module Comparator_stru() will have assign variables as Gt, Lt, Eq instead of Gt_O, Lt_O, Eq_O as this module is not having Gt_O, Lt_O, Eq_O as outputs.

Trouble with 8-bit Carry Lookahead Adder in Verilog

I'm new to Verilog programming. I'm trying to put together an 8-bit Carry Lookahead Adder as a step toward building a 64-bit CLA. Basically, the way I implemented it is I use 2 4-bit CLA "blocks" to create the 8-bit CLA. I'll provide my code, then an explanation of the problem I'm having.
Code below:
// 4-BIT CLA CODE
module CLA4Bit(A, B, carryIn, carryOut, PG, GG, Sum);
input[3:0] A, B;
input carryIn;
output carryOut;
output PG;
output GG;
output[3:0] Sum;
wire[3:0] G, P, C;
assign G = A & B;
assign P = A ^ B;
assign Sum = P ^ C;
assign C[0] = carryIn;
assign C[1] = G[0] | (P[0] & C[0]);
assign C[2] = G[1] | (P[1] & G[0]) | (P[1] & P[0] & C[0]);
assign C[3] = G[2] | (P[2] & G[1]) | (P[2] & P[1] & G[0]) | (P[2] & P[1] & P[0] & C[0]);
assign PG = P[3] & P[2] & P[1] & P[0];
assign GG = G[3] | (P[3] & G[2]) | (P[3] & P[2] & G[1]) | (P[3] & P[2] & P[1] & G[0]);
endmodule
// 8-BIT CLA CODE BELOW
module CLA8Bit(A, B, carryIn, carryOut, Sum);
// 8-bit wire for the inputs A and B
input[7:0] A, B;
// Wire for the ORIGINAL carry-in
input carryIn;
// Wire for the carryOut
output carryOut;
// Wire that carries the Sum of this CLA
output[7:0] Sum;
// Wires for the propagate of the first 4-bit block (p3)
// and the second (p7)
wire p3, p7;
// Wires for the generate of the first 4-bit block (g3)
// and the second (g7)
wire g3, g7;
// Wires for the carry of the first block (c3) and the
// second (c7)
wire c3, c7;
// The two 4-bit CLA blocks that make up the 8-bit CLA
CLA4Bit block1(A[3:0], B[3:0], carryIn, c3, p3, g3, Sum[3:0]);
CLA4Bit block2(A[7:4], B[7:4], c3, c7, p7, g7, Sum[7:4]);
endmodule
I wrote a basic testbench to test my code:
module CLA_TB();
// TEST THE 8-BIT CLA
// Inputs
reg[7:0] A;
reg[7:0] B;
reg carryIn;
// Outputs
wire carryOut;
wire[7:0] Sum;
wire PG;
wire GG;
// Instantiate the 8-bit CLA
CLA8Bit CLA8BitDUT (
.A(A),
.B(B),
.carryIn(carryIn),
.carryOut(carryOut),
.Sum(Sum)
);
// Initialize the testbench signals
initial
begin
// Start with the carryIn set to 0
assign carryIn = 0;
// The standard first test. Set
// A = b0000 0001 and B = b0000 0001
// Answer should be Sum = b0000 0010
assign A = 8'b00000001;
assign B = 8'b00000001;
#20
// Next, set A = b0001 1011 and
// B = b1101 0111. Answer should
// be Sum = b1111 0010 = hF2.
assign A = 8'b00011011;
assign B = 8'b11010111;
#20
// Finally, try setting the carryIn
// to 1 and then test A = b0111 1011
// and B = b1101 0011. Answer should be
// Sum = 0100 1111 w/ overflow carry
assign carryIn = 1'b1;
assign A = 8'b01111011;
assign B = 8'b11010011;
#20
$finish;
end
endmodule
So the problem is, in my simulations of the testbench (I use ModelSim), the first 4 bits of the Sum (which correspond to the first 4-bit CLA instance in the 8-bit CLA module) are given as X in the Wave page. The second 4 bits add just fine, though.
After doing some research, I found out that X's are displayed in Verilog when a wire has more than one driver (source of the signal?). However, I don't see any place where I send more than one signal to my first 4-Bit CLA instance in the 8-Bit CLA module. Also, if something like that were the cause, then I don't know why it wouldn't happen to the second set of 4 bits as well, since both the 4-bit CLAs are set up very similarly.
Why is this happening?
X's are displayed in Verilog when a wire has more than one driver
That is true but it is only part of the story. There are other cases which produce X'es:
If a reg is not given a value it will be X.
If a Z is used in an expression it will produce an X .
Your waveform has some obvious 'Z' (blue) lines one it.
If you following the signals back to where they originate: your 4-bit adder never assigns a value to carryOut.
Then you make the same error in CLA8Bit.
If you see a 'Z' in a simulation: jump on it! 99.9% of the time you have an wire which has not been given a value!

Error using for loop [procedural assignment to a non-register i is not permitted]

I'm not really experienced with Verilog. I'm trying to make an RCA using a for loop but I'm getting an error when trying to synthesize the modules.
The error I'm getting is
procedural assignment to a non-register i is not permitted
//1-bit full adder
module fadder (s, cout, a, b, cin);
input a, b, cin;
output s, cout;
assign s = (a ^ b) ^ cin;
assign cout = ((a & b) | ((a | b) & cin));
endmodule
//RCA Logic
module part1(s, cout, a, b, cin, clk);
parameter BIT_WIDTH = 128;
input [BIT_WIDTH-1:0] a, b;
input cin;
input clk;
output cout;
output [BIT_WIDTH-1:0] s;
wire [BIT_WIDTH:0] cin_wire;
assign cin_wire[0] = cin;
genvar i;
generate
always#(posedge clk)
begin
for(i = 0; i <= BIT_WIDTH-1; i = i + 1) //error is on this line
begin:
fadder fadder_inst (.s(s[i]), .cout(cin_wire[i+1]), .a(a[i]), .b(b[i]), .cin(cin_wire[i]));
end
end
endgenerate
assign cout = cin_wire[BIT_WIDTH];
endmodule
Any help is appreciated. Thanks
generate
for(i = 0; i <= BIT_WIDTH-1; i = i + 1)
begin
fadder fadder_inst (.s(s[i]), .cout(cin_wire[i+1]), .a(a[i]), .b(b[i]), .cin(cin_wire[i]));
end
endgenerate
You can not generate the modules inside always block.
You have to seperately manipulate input inside always block before connecting to fadder_inst.
What I guess is, RCA is not clock dependent. Its purly asynchronous circuit.
You cannot instantiate a module inside a procedural block (initial,
always, always_comb, always_ff, always_latch, final, task, function).
You can do like following to serve your purpose.
module fadder (clk, s, cout, a, b, cin);
input a, b, cin, clk;
output reg s, cout;
always # (posedge clk)
begin
s = (a ^ b) ^ cin;
cout = ((a & b) | ((a | b) & cin));
end
endmodule
//RCA Logic
module part1(s, cout, a, b, cin, clk);
parameter BIT_WIDTH = 128;
input [BIT_WIDTH-1:0] a, b;
input cin;
input clk;
output cout;
output [BIT_WIDTH-1:0] s;
wire [BIT_WIDTH:0] cin_wire;
assign cin_wire[0] = cin;
genvar i;
generate
begin
for(i = 0; i <= BIT_WIDTH-1; i = i + 1) //error is on this line
begin:
fadder fadder_inst (.clk(clk), .s(s[i]), .cout(cin_wire[i+1]), .a(a[i]), .b(b[i]), .cin(cin_wire[i]));
end
end
endgenerate
assign cout = cin_wire[BIT_WIDTH];
endmodule
As others have pointed out, you cannot instantiate modules inside an always block. The need to be separated and a new wire needs to be created to connect the two.
In the below example cout and s are reg type outputs. There is an added wire s_wire (following your naming convention based cin_wire) which is connected to the s output of the fadder_inst instances. part1's s and cout output is synchronously assigned to s_wire and cin[BIT_WIDTH] respectivly. Note that they are assigned with non-blocking assignments (<=).
// ...
output reg cout;
output reg [BIT_WIDTH-1:0] s;
wire [BIT_WIDTH-1:0] s_wire;
wire [BIT_WIDTH:0] cin_wire;
assign cin_wire[0] = cin;
genvar i;
generate
for(i = 0; i <= BIT_WIDTH-1; i = i + 1)
begin
fadder fadder_inst (.s(s_wire[i]), .cout(cin_wire[i+1]), .a(a[i]), .b(b[i]), .cin(cin_wire[i]));
end
endgenerate
always#(posedge clk)
begin
s <= s_wire;
cout <= cin_wire[BIT_WIDTH];
end
// ...

Compile issues with verilog

Can anyone see any blatant errors as to why this does not compile. I think the logic is correct for most of these operations. Its most likely syntax errors.
the only thing i can think of is the switch statement isn't written correctly as well as the add module. Each of the foury bit statements are connected to one of the modules below it. (bitwise not binary)
module _4bitALU(C , O , A , B , Switch);
input[3:0] A ;
input [3:0] B;
input [3:0] Switch;
output [3:0] O;
output C;
case(Switch)
4'B0000: notop(O , A);
4'B0001: andop(O , A , B);
4'B0010: orop(O , A , B);
4'B0011: xorop(O , A , B);
4'B1000: addop(C , O , A , B);
endcase // case (Switch)
endmodule // _4bitALU
module notop(O , A);
input [3:0] A;
output [3:0] O;
assign O = ~A;
endmodule // notop
module andop(O , A , B);
input [3:0] A;
input [3:0] B;
output [3:0] O;
assign O = (A & B);
endmodule // andop
module orop(O , A , B);
input [3:0] A;
input [3:0] B;
output [3:0] O;
assign O = (A | B);
endmodule // orop
module xorop(O , A , B);
input [3:0] A;
input [3:0] B;
output [3:0] O ;
assign O = (A ^ B);
endmodule // xorop
module addop(C , O , A , B);
input [3:0] A;
input [3:0] B;
output [3:0] O;
output C;
assign C1 = (A[0] & B[0]);
assign C2 = ((A[1] & B[1]) | (A[1] & C1) | (B[1] & C1));
assign C3 = ((A[2] & B[2]) | (A[2] & C2) | (B[2] & C2));
assign C = ((A[3] & B[3]) | (A[3] & C3) | (B[3] & C3));
assign O[0] = (A[0] ^ B[0]);
assign O[1] = ((A[1] ^ B[1] ^ C1) | (A[1] & B[1] & C[1]));
assign O[2] = ((A[2] ^ B[2] ^ C2) | (A[2] & B[2] & C[2]));
assign O[3] = ((A[3] ^ B[3] ^ C3) | (A[3] & B[3] & C[3]));
assign O[4] = ((A[4] ^ B[4] ^ C4) | (A[4] & B[4] & C[4]));
endmodule // addop
There are quite a few problems in the _4bitALU module:
The case statement is not inside an always block.
You can't "call" other modules like you do in the case branches, instead you need to create instances of those modules and assign the wires which connect to those instances within the case branches to the desired output(s).
These issues are rather basic Verilog, therefore I suggest you read up on how it is used (maybe this tutorial might help). Remember that you are (in most cases anyway) trying to describe the structure of hardware, not a software program that just gets executed.

Resources