verilog debugging - verilog

I don't know what is wrong with the code below. Can someone help me debug?
module iloop(z,a);
input [31:0] a;
output z;
reg [4:0] i;
reg s, z;
initial begin
s = 0;
for(i=0; i<32; i=i+1) s = s | a[i];
z = !s;
end
endmodule

Your code has an infinite loop. You have declared i as a 5-bit reg, which means its range of values is (decimal) 0 to 31. But, your for loop checks if i < 32, which is always true.
Once i=31, i is incremented and rolls over to 0.
$display is your friend. If you add it to your for loop, you will see the problem:
for(i=0; i<32; i=i+1) begin $display(i); s = s | a[i]; end
I think you want i<31.
Or, maybe you want to OR all the bits of a together, using the bit-wise OR operator:
s = |a;
You should explain in words what you are trying to achieve.

Related

Does SystemVerilog Generate support delays?

I thought of generating clock using genvar like below:
reg [7:0]clk;
genvar i;
generate
for (i=0; i < 7; i++) begin
#1 clk[i]=~clk[i];
end
endgenerate
I am getting an error:
error: near "#": syntax error, unexpected '#'
How can we resolve it? Can I use delays inside generate block?
I feel it isn't necessary to have a generate, you can use the for loop directly in an always block:
reg [7:0] clk;
integer i;
always begin
#1;
for(i = 0; i < 7; i = i + 1)
clk[i] = ~clk[i];
end
Nevertheless, if all the bits are toggled at the same time, you can simplify it with:
always
#1 clk = ~clk; //..bitwise invert the array
Yes, generate blocks support delays. To fix your problem, use a procedural always block:
reg [7:0] clk;
genvar i;
generate
for (i=0; i < 7; i++) begin
always #1 clk[i]=~clk[i];
end
endgenerate
It looks like OP wanted to have a sequential delay model. In this case the code should look like this:
always begin
for(i = 0; i < 7; i = i + 1)
#1 clk[i] = ~clk[i];
end

Verilog test bench for loop(priority, problem with value)

For i=0 and j=0 this code makes my a,b,cin and s signals to be xxxxxxxx.
For i=0 and j=1 my a,b,cin and s are all 00000000.Which should be the result for my adder for i=0 j=0 cin =0. Whats wrong? I am sure my adder module is correct.
http://prntscr.com/lpngel
http://prntscr.com/lpngih (...and so on)
Most of the trouble came at first with the for loops and began when some of the values werent printed and then after i added begin end in each loop i saw the full loop result whith the above problem^^^^^.Still dont know how it worked but it did
module test_cla4_n;
reg [7:0] a,b;
reg cin;
wire [7:0] s;
wire cout;
integer i;
integer j;
integer cv;
cla4_n#(.n(8)) UUT
(.a(a), .b(b),
.cin(cin),
.s(s), .cout(cout));
initial
begin
for(cv=0;cv<=1;cv=cv+1)
begin
for (i=0;i<6;i=i+1)
begin
for (j=0;j<6;j=j+1)
begin
#100 a = j; b = i; cin = cv;
end
end
end
end
initial
begin
$monitor($time, ,"a=%9b, b=%9b, cin=%b, sum=%9b", a, b, cin, s);
end
endmodule
Whether you put the #100 delay before or after the assignments does not matter as long as you understand how the delay works w.r.t. the loop.
The only place begin/end is required anywhere in the code you show is with the innermost for(j=0; ` loop.
All 4-state variables and nets in verilog are initialized with 'x'. Therefore, before you drive something in your simulation, all signals will remain 'x'.
In your test bench you use #100 delay in your loop. In your expression it means that all the assignments which follow #100 will happen only after 100 verilog simulation cycles (or whatever you set with 'timescale'). But before it all your values will remain 'x'.
Now when #100 triggers in you will have the following:
#100
a = j; <-- 0
b = i; <-- 0
cin = cv; <-- 0
j = j + 1; <-- 1 << from the loop
You end up with a = 0, b = 0, c = 0, and j will change to '1'.
Now your simulation will kick in and calculate the results for the above. You can continue this train of thoughts for the rest of simulation.
In order for all those statement to happen in side the loop after #100, yes you need to put begin/end around them. Otherwise only the first statement will be evaluated in the innermost loop. This is similar to any programming language.
for (j=0;j<6;j=j+1)
begin
#100 // wait here for 100 simulation ticks
a = j;
b = i;
cin = cv;
end

verilog compile error - "variable not constant"

Why am I getting error "q is not constant"?
module prv(
input [7:0]x,
input [7:0]y,
output [49:0]z
);
wire [24:0]q;
assign z=1;
genvar k;
for (k=50; k<0; k=k-1)
begin
wire [25:0]a;
assign a=0;
assign q= x;
genvar i;
for(i=0; i<8; i=i+1)
begin
if(q[0]==1)
begin
assign a=a+z;
end
assign {a,q}={a,q}>>1;
end
assign z={a[24:0],q};
end
endmodule
I'm afraid that you are trying to use Verilog the wrong way. q is a wire, not a variable (a reg) so it cannot be assigned with a value that includes itself, because that would cause a combinational loop. You are using the assign statement as if it were a regular variable assignment statement and it's not.
Declare a and q as reg, not wire. i and k don't need to be genvars variables, unless you are trying to generate logic by replicating multiple times a piece of code (description). For for loops that need to behave as regular loops (simulation only) use integer variables.
Besides, behavioral code must be enclosed in a block, let it be combinational, sequential, or initial.
A revised (but I cannot make guarantees about its workings) version of your module would be something like this:
module prv(
input wire [7:0] x,
input wire [7:0] y,
output reg [49:0] z
);
reg [24:0] q;
reg [25:0] a;
integer i,k;
initial begin
z = 1;
for (k=50; k<0; k=k-1) begin
a = 0;
q = x;
for (i=0; i<8; i=i+1) begin
if (q[0] == 1) begin
a = a + z;
end
{a,q} = {a,q}>>1;
end
z = {a[24:0],q};
end
endmodule

Verilog HDL syntax error near text "for"; expecting "endmodule"

So I just got around to learning verilog and I was implementing a basic binary adder in it.
From my limited understanding of verilog, the following should add two 16-bit values.
module ADD(X, Y, Z);
input[15:0] X;
input[15:0] Y;
output Z[15:0];
wire C[15:0];
assign C[0] = 0;
integer i;
for(i=1; i<16; i=i+1) begin
assign C[i]=(X[i-1]&Y[i-1])|(X[i-1]&C[i-1])|(Y[i-1]&C[i-1]);
end
for(i=0; i<16; i=i+1) begin
assign Z[i]=X[i]^Y[i]^C[i];
end
endmodule
However, I get an error when I try to synthesize the above.
Error (10170): Verilog HDL syntax error at add.v(10) near text "for"; expecting "endmodule"
I'm not sure what is wrong with the code. Any help is appreciated!
The for-loop is used outside of an always block, so i needs to be a genvar instead of an integer. Also, you probably want Z and C to declared an packed arrays instead of unpacked, mo the [15:0] to the other side.
output [15:0] Z; // make as packed bits
wire [15:0] C;
assign C[0] = 0;
genvar i; // not integer
generate // Required for IEEE 1364-2001, optional for *-2005 and SystemVerilog
for(i=1; i<16; i=i+1) begin
assign C[i]=(X[i-1]&Y[i-1])|(X[i-1]&C[i-1])|(Y[i-1]&C[i-1]);
end
for(i=0; i<16; i=i+1) begin
assign Z[i]=X[i]^Y[i]^C[i];
end
endgenerate // must be matched with a generate
Alternative solution 1: use an always block
output reg[15:0] Z; // make as reg
reg [15:0] C;
integer i; // integer OK
always #* begin
for(i=1; i<16; i=i+1) begin
if (i==0) C[i] = 1'b0;
else C[i]=(X[i-1]&Y[i-1])|(X[i-1]&C[i-1])|(Y[i-1]&C[i-1]);
Z[i]=X[i]^Y[i]^C[i];
end
end
Alternative solution 2: bit-wise assignment
output [15:0] Z;
wire [15:0] C = { (X&Y)|(X&C)|(Y&C) , 1'b0 };
assign Z = X^Y^C;
Alternative solution 3: behavioral assignment
output [15:0] Z;
assign Z = X+Y;
Working examples here
Change the definition of i from integer to genvar.
Notice that for loops can be used either in an always block or in a generate block. The latter is implicitly the context that you are using it in your code. In generate blocks, the loop variable should be of type genvar.
More info in IEEE Std 1800-2012

In synthesizable verilog, can we use assign statement in generate block?

For example, I have the below piece of code. Can we assign wire inside the generate block in synthesizable verilog? Can we use assign statement inside the generate block in synthesizable verilog?
genvar i;
generate
for (i = 0; i < W; i=i+1) begin:m
wire [2:0] L;
assign L[1:0] = { a[i], b[i] };
end
endgenerate
Yes. It is possible. A generate statement is just a code generator directive to the synthesizer. Basically, it is just loop unrolling. This is if the loop can be statically elaborated. That is, the number of times the loop is to executed should be determinable at compile time.
genvar i;
generate
for (i = 0; i < 2 ; i++) {
assign x[i] = i;}
endgenerate
unrolls into
assign x[0] = 0;
assign x[1] = 1;
In synthesizeable Verilog, it is possible to use an assign statement inside of a generate block. All a generate block does is mimic multiple instants. Be careful though, because just like a for loop, it could be very big space-wise.
You can use assign in generate statment, it is quite common to help parameterise the hook up modules
The original code has some issues: L is defined multiple times and it is only assigned 2 out of 3 bits
genvar i;
generate
for (i = 0; i < W; i=i+1) begin:m
wire [2:0] L;
assign L[1:0] = { a[i], b[i] };
end
endgenerate
Could be changed to:
localparam W = 4;
reg [W-1:0] a;
reg [W-1:0] b;
wire [1:0] L [0:W-1];
genvar i;
generate
for (i = 0; i < W; i=i+1) begin:m
assign L[i] = { a[i], b[i] };
end
endgenerate
Here L[i] selects the i'th wire [1:0] part of L. While a[i] and b[i] are bit selects.

Resources