I wrote a module in System Verilog, I need 32 modules, so I am using generate statement for instantiation.
The problem is that in every rising edge of clock I need to instantiate new values to the modules and then need to choose one of them (in the same posedge clock
, depending on the outputs of the modules, in my case the min between all the module output).
How can I do that?
This is my current version of the code:
genvar j;
generate
for (int j=0; j<32; j++)
begin: module_instant_loop
always @(posedge Clock)
begin
MyUnit unit[j] (.A(TEST1[j],.B(TEST2[j]),.OUT(MYOUT[j]);
end
end
end
endgenerate
And this is the code that I want to add:
for (int i=0; i<32; i++)
begin
if (MYOUT[i] < MINIMUM) MINIMUM=MYOUT[i];
if (MYOUT[i] > MAXIMUM) MAXIMUM=MYOUT[i];
end
How can I add the loop to my code?
1 Answer 1
You cannot instantiate a module instance inside an always block. You choices are to move the synchronous logic inside MyUnit
or flop the output MyUnit
at the same level.
Typically, you want to flop your final outputs. You may put some combinational logic after the flop, but be aware this can can make flop-to-flop timing across different modules harder to calculate.
So assuming MINIMUM
and MAXIMUM
are the values you want flopped, I would recommend the following logic:
always_comb begin
// Set defaults
next_MINIMUM = '1; // fill with all 1s
next_MAXIMUM = '0; // fill with all 0s
// Alternative default with the previous MIN/MAX values
//next_MINIMUM = MINIMUM;
//next_MAXIMUM = MAXIMUM;
// Update MIN/MAX based on MYOUT
foreach(MYOUT[idx]) begin // IEEE Std 1800-2012 12.7.3 The foreach-loop
if (MYOUT[idx] < next_MINIMUM) next_MINIMUM=MYOUT[idx];
if (MYOUT[idx] > next_MAXIMUM) next_MAXIMUM=MYOUT[idx];
end
end
always_ff @(posedge clk) begin
MINIMUM <= next_MINIMUM;
MAXIMUM <= next_MAXIMUM;
end
It is a best practice to always assign a flop with non-blocking. Blocking assignments are needed to properly calculate the next value. Therefore, the intermediate signals next_*
. When using SystemVerilog, it is recommend to use always_comb
and always_ff
instead of always
(See IEEE Std 1800-2012 § 9.2.2.2.2 always_comb compared to always @*).
int
in the for loop inside the generate statement - j is already declared as a genvar. \$\endgroup\$