I have some Verilog module with multidimensional outputs (to 7-segment LED panels of my DE1-SoC). I want to make the outputs registered. To test it, I give some dummy code to one of LED digits. Its RTL simulation passes OK, it's even compiled by Quartus, but actually it does not work.
Code:
module Top
(
input CLK50,
output reg[6:0] HEX[5:0]
);
genvar i;
generate
for(i = 0; i < 6; i++)
begin: test
initial
//always@(posedge CLK50)
begin
HEX[i][6:0] = 7'b101_0101;
end
end
endgenerate
endmodule
Alas, my Quartus synthesizer gives sais me the following warning:
Code:
Warning (10855): Verilog HDL warning at Top.v(20): initial value for variable HEX should be constant
and says that that all the HEX pins are stuck on GND:
Code:
Warning (13410): Pin "HEX[0][0]" is stuck at GND
Warning (13410): Pin "HEX[0][1]" is stuck at GND
Warning (13410): Pin "HEX[0][2]" is stuck at GND
Warning (13410): Pin "HEX[0][3]" is stuck at GND
Warning (13410): Pin "HEX[0][4]" is stuck at GND
Warning (13410): Pin "HEX[0][5]" is stuck at GND
Warning (13410): Pin "HEX[0][6]" is stuck at GND
Warning (13410): Pin "HEX[1][0]" is stuck at GND
Warning (13410): Pin "HEX[1][1]" is stuck at GND
Warning (13410): Pin "HEX[1][2]" is stuck at GND
Warning (13410): Pin "HEX[1][3]" is stuck at GND
Warning (13410): Pin "HEX[1][4]" is stuck at GND
Warning (13410): Pin "HEX[1][5]" is stuck at GND
Warning (13410): Pin "HEX[1][6]" is stuck at GND
Warning (13410): Pin "HEX[2][0]" is stuck at GND
Warning (13410): Pin "HEX[2][1]" is stuck at GND
Warning (13410): Pin "HEX[2][2]" is stuck at GND
Warning (13410): Pin "HEX[2][3]" is stuck at GND
Warning (13410): Pin "HEX[2][4]" is stuck at GND
Warning (13410): Pin "HEX[2][5]" is stuck at GND
Warning (13410): Pin "HEX[2][6]" is stuck at GND
Warning (13410): Pin "HEX[3][0]" is stuck at GND
Warning (13410): Pin "HEX[3][1]" is stuck at GND
Warning (13410): Pin "HEX[3][2]" is stuck at GND
Warning (13410): Pin "HEX[3][3]" is stuck at GND
Warning (13410): Pin "HEX[3][4]" is stuck at GND
Warning (13410): Pin "HEX[3][5]" is stuck at GND
Warning (13410): Pin "HEX[3][6]" is stuck at GND
Warning (13410): Pin "HEX[4][0]" is stuck at GND
Warning (13410): Pin "HEX[4][1]" is stuck at GND
Warning (13410): Pin "HEX[4][2]" is stuck at GND
Warning (13410): Pin "HEX[4][3]" is stuck at GND
Warning (13410): Pin "HEX[4][4]" is stuck at GND
Warning (13410): Pin "HEX[4][5]" is stuck at GND
Warning (13410): Pin "HEX[4][6]" is stuck at GND
Warning (13410): Pin "HEX[5][0]" is stuck at GND
Warning (13410): Pin "HEX[5][1]" is stuck at GND
Warning (13410): Pin "HEX[5][2]" is stuck at GND
Warning (13410): Pin "HEX[5][3]" is stuck at GND
Warning (13410): Pin "HEX[5][4]" is stuck at GND
Warning (13410): Pin "HEX[5][5]" is stuck at GND
Warning (13410): Pin "HEX[5][6]" is stuck at GND
Ignore initial constructs is off. When I replace initial to always@(posedge CLK50), just for test, it works fine, but I want initial values in my registers.
How can I solve the problem?
- - - Updated - - -
UPD: It also sais that
Code:
Warning (10855): Verilog HDL warning at Top.v(14): initial value for variable HEX should be constant
- - - Updated - - -
UPD: It looks like *initial* statement can be synthesised, but multiple *initial* statement cannot.
Don't you know a way to use *generate-for* construction inside *initial* statement?
P.S. Cannot you also tell me the difference between the two designs?
Works:
Code:
module Top
(
input CLK50,
output reg[6:0] HEX[5:0]
);
integer i;
initial begin
for(i = 0; i < 6; i++)
begin
HEX[i][6:0] = 7'b101_0101;
end
end
endmodule
Fails:
Code:
module Top
(
input CLK50,
output reg[6:0] HEX[5:0]
);
genvar i;
generate
for(i = 0; i < 6; i++)
begin: test
initial
begin
HEX[i][6:0] = 7'b101_0101;
end
end
endgenerate
endmodule
Unravel the for loop to see what the code looks like.
The one that works results in this:
Code:
integer i;
initial begin
HEX[0][6:0] = 7'b101_0101;
HEX[1][6:0] = 7'b101_0101;
HEX[2][6:0] = 7'b101_0101;
...
HEX[5][6:0] = 7'b101_0101;
end
The code that doesn't work does this:
Code:
initial begin
HEX[0][6:0] = 7'b101_0101;
end
initial begin
HEX[1][6:0] = 7'b101_0101;
end
initial begin
HEX[2][6:0] = 7'b101_0101;
end
...
initial begin
HEX[5][6:0] = 7'b101_0101;
end
Which means you are assigning an array in multiple blocks, which isn't allowed. This is similar to the problem where many new Verilog coders do something like this:
Code:
always @ (posedge reset) begin
if (reset) begin
my_signal <= 1'b0;
end
end
always @ (posedge clock) begin
if (enable) begin
my_signal <= my_input;
end
end
Excuse me, I meant — what was the difference between this
Does not synthesize
Code:
module Top
(
input CLK50,
output reg[5:0][6:0] HEX
);
initial begin
genvar i;
generate
for(i = 0; i < 6; i++) begin: test
HEX[i][6:0] = 7'b101_0101;
end
endgenerate
end
endmodule
and that (does synthesize)
Code:
module Top
(
input CLK50,
output reg[5:0][6:0] HEX
);
initial begin
integer i;
for(i = 0; i < 6; i++) begin
HEX[i][6:0] = 7'b101_0101;
end
end
endmodule
If you look in the LRM 12.2 states the allowed procedural statements are:
— Selection statements (see 12.4 and 12.5)
— Loop statements (see 12.7)
— Jump statements (see 12.8)
— Sequential and parallel blocks (see 9.3)
— Timing controls (see 9.4)
— Process control (see 9.5 through 9.7)
— Procedural assignments (see 10.4 through 10.9)
— Subroutine calls (see Clause 13)
As you can see generate is not included. Generate isn't a procedural statement, therefore it can't exist in an initial block.
In reply to the question in #2, there is no functional difference between the two code forms. It is just that the second case with the generate-for loop, the synthesis tool is not smart enough to figure out that the assignment statements will be to mutually exclusive elements of the array. The synthesis tool has a limitation that it can only figure that out if the code is within a single initial block.