2
\$\begingroup\$

I have been trying to run this Verilog code which simulates traffic decongestion, but I am getting this error. I have also tried to use an always block, but I am still not able to resolve it. Following are my design and testbench files in that order.

// main module
module test2(v1, v2, v3, v4, v5, h, l, lane_no);
input v1, v2, v3, v4, v5, h, l;
output[1 : 0] lane_no;
wire local;
wire x1, x2, p;
wire e3, e2, e1;
assign local = v1 & v2 & v3;
wire[2 : 0] count1 = 3'b000;
wire[2 : 0] count2 = 3'b000;
wire a1, a2, a3, b1, b2, b3;
assign a1 = count1[0];
assign a2 = count1[1];
assign a3 = count1[2];
assign b1 = count2[0];
assign b2 = count2[1];
assign b3 = count2[2];
if (local) begin // This is Line 26 (see error messages)
 assign lane_no = 2'b11;
end
else
begin
 assign e3 = ~(a3^b3);
 assign e2 = ~(a2^~b2);
 assign e1 = ~(a1^~b1);
 assign x1 = (~a3 & b3) + (e3 & ~a2 & b2) + (e3 & e2 & ~a1 & b1);
 assign x2 = ~x1;
 assign p = e3 & e2 & e1;
 if (p == 1)
 begin
 if (count1 == 3'b000)
 begin
 assign lane_no = 2'b01;
 assign count1 = count1 + 3'b001;
 assign count1 = count1 - 3'b001;
 end
 end
end
endmodule

I am getting this error when I execute the following command:

harshal@dl8-OptiPlex-9010:~/Desktop$ iverilog test.v testbench.v 
test.v:26: error: Unable to bind parameter `local' in `main.dut'
test.v:26: error: Cannot evaluate genvar conditional expression: 
local
test.v:26: error: Unable to bind parameter `local' in `main.dut'
test.v:26: error: Cannot evaluate genvar conditional expression: 
local
4 error(s) during elaboration.
module main;
 reg v1,v2,v3,v4,v5,h,l;
 wire[2:0] lane_no;
 test2 dut(v1,v2,v3,v4,v5,h,l,lane_no);
 
 initial begin
 v1=1;v2=1;v3=1;v4=0;v5=0;h=1;l=0;
 #10 v1=1;v2=0;v3=1;v4=0;v5=0;h=1;l=0;
 #10 v1=1;v2=1;v3=0;v4=0;v5=0;h=0;l=1;
 end
 initial begin
 $monitor(" output= %b%b%b",lane_no);
 end
endmodule

I am not able to figure out the exact error as I am beginner in Verilog programming.

toolic
10.8k11 gold badges31 silver badges35 bronze badges
asked Jan 3, 2023 at 5:11
\$\endgroup\$
1
  • \$\begingroup\$ Can you add the code with always block and error messages for the code with always block? \$\endgroup\$ Commented Jan 5, 2023 at 6:19

2 Answers 2

2
\$\begingroup\$

When the Verilog compiler sees an if/else which is not inside an always block, it assumes the code is a generate construct. It expects the if conditional expression to be a constant, which means it expects local to be a parameter, for example. However, you declared local to be a variable type (wire). This explains the error message you received. Refer to IEEE Std 1800-2017, section 27. Generate constructs.

It is possible to place the if/else code inside an always block, but other changes are needed as well. All signals assigned inside the always procedural block should be declared as reg, not wire. Also, there is no need for the assign keyword in the always block.

module test2(v1,v2,v3,v4,v5,h,l,lane_no);
 input v1,v2,v3,v4,v5,h,l;
 output reg [1:0] lane_no;
 wire local;
 reg x1,x2,p;
 reg e3,e2,e1;
 assign local=v1&v2&v3;
 reg [2:0] count1=3'b000;
 reg [2:0] count2=3'b000;
 wire a1,a2,a3,b1,b2,b3;
 assign a1=count1[0];
 assign a2=count1[1];
 assign a3=count1[2];
 assign b1=count2[0];
 assign b2=count2[1];
 assign b3=count2[2];
 always @* begin
 if(local) begin
 lane_no= 2'b11;
 end else
 begin
 e3=~(a3^b3);
 e2=~(a2^~b2);
 e1=~(a1^~b1);
 x1=(~a3&b3)+(e3&~a2&b2)+(e3&e2&~a1&b1);
 x2=~x1;
 p=e3&e2&e1;
 if(p==1) begin
 if(count1==3'b000)
 begin
 lane_no=2'b01;
 count1=count1+3'b001;
 count1=count1-3'b001;
 end
 end
 end
 end
endmodule

I used emacs Verilog-mode to reformat the code using reasonable indentation.

This code compiles without errors for iverilog.


Note that local is now a keyword for SystemVerilog (IEEE Std 1800). Apparently, it has not yet been implemented with iverilog, but I recommend you change local to something else like local1.

answered Jan 3, 2023 at 12:19
\$\endgroup\$
0
1
\$\begingroup\$

Your problem lies in the use of if-else statements otside of a procedural block (always, etc).

Your code below will not work:

if(local) begin 
assign lane_no= 2'b11;
end
else
begin
assign e3=~(a3^b3);
...

You need to think about what the code will describe in terms of hardware, as this is not a programming language, but a hardware description language.

Here you say "if signal local is high, add some circuitry to set lane_no. Otherwise, remove that circuitry and add some other circuitry to assign e3 etc.". This can't work because the hardware must be fixed once synthesis is complete - you can't suddenly add extra circuitry at run time.

To use if-else you should switch to using always blocks and =/<= rather than assign (note that this will require the target variables to be reg rather than wire):

reg x;
always @ (trigger) begin
 if (condition) begin
 x <= val_if_true;
 end else begin
 x <= val_if_false;
 end
end

In other cases you can use the ternary operator with assign statements if appropriate:

assign x = (condition) ? val_if_true : val_if_false;

I would suggest going back to basics and finding a tutorial on how to program in Verilog. This is one that I found quite useful way back when I was learning Verilog.

answered Jan 3, 2023 at 12:18
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.