Multidimensional array of registers with initialization

Status
Not open for further replies.

Nuclear_Carlson

Newbie level 4
Joined
Nov 18, 2010
Messages
6
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,309
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?
 

Thank you, comrade! It worked!

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
 

I believe, you'll use a regular for loop inside the initial block.

- - - Updated - - -

As you found out, multiple initial statements aren't supported. The other syntax is a straightforward way to achieve what you want, I think.
 
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.
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…