2
\$\begingroup\$

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?

user2943160
2,9381 gold badge19 silver badges33 bronze badges
asked May 31, 2015 at 23:58
\$\endgroup\$
1
  • \$\begingroup\$ You shouldn't have the int in the for loop inside the generate statement - j is already declared as a genvar. \$\endgroup\$ Commented Jun 1, 2015 at 0:25

1 Answer 1

3
\$\begingroup\$

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 @*).

answered Jun 1, 2015 at 4:34
\$\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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.