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.
-
\$\begingroup\$ Can you add the code with always block and error messages for the code with always block? \$\endgroup\$Shashank V M– Shashank V M2023年01月05日 06:19:05 +00:00Commented Jan 5, 2023 at 6:19
2 Answers 2
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
.
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.