0

I am trying to do a cummulative sum with a series of nested for loops and am having no luck. I think I need a better understanding of how Verilog unrolls the for loops before I can really visualize how to solve my problem.

Essentially I have a series of tap outputs (tap_output_i and tap_output_q) that are 3D arrays (src, dst, tap). I want to sum all the source and taps going to a particular destination each clock.

Here is what I have that does not work (out_sig is 0 every time):

//NODES = 2
wire signed [DAC_BUS_WIDTH-1:0]      out_sig_i [NODES-1:0];
wire signed [DAC_BUS_WIDTH-1:0]      out_sig_q [NODES-1:0];
reg signed [DAC_BUS_WIDTH-1:0] out_sig_i_reg[NODES-1:0];
reg signed [DAC_BUS_WIDTH-1:0] out_sig_q_reg[NODES-1:0];

integer dstVal,srcVal, tapVal;
//generate
always @(posedge clk) begin: AlwaysSummingForLoop
  for (dstVal=0; dstVal<2; dstVal=dstVal+1) begin:SummingForLoop
    out_sig_i_reg[dstVal] <= 0;
    out_sig_q_reg[dstVal] <= 0;
      for (srcVal=0; srcVal<2; srcVal=srcVal+1) begin:SrcForLoop
        if(srcVal != dstVal) begin:innerIf
             for (tapVal=0; tapVal<8; tapVal=tapVal+1) begin:tapSum
                out_sig_i_reg[dstVal] <= out_sig_i_reg[dstVal] + tap_output_i[srcVal][dstVal][tapVal];
                out_sig_q_reg[dstVal] <= out_sig_q_reg[dstVal] + tap_output_q[srcVal][dstVal][tapVal];
             end
        end
      end
    end
end
//endgenerate
assign out_sig_i[0] = out_sig_i_reg[0];
assign out_sig_q[0] = out_sig_q_reg[0];
assign out_sig_i[1] = out_sig_i_reg[1];
assign out_sig_q[1] = out_sig_q_reg[1];

Where I am running into issues is resetting the cumulative (out_sig_i_reg and out_sig_q_reg) sum every count...

1
  • Yes, I am using out_sig_i_reg and out_sig_q_reg as my cummultive sum. What I can't figure out is how to get it to cumulatively sum AND reset to zero each time before the summing... Commented Feb 5, 2015 at 13:59

1 Answer 1

6

<= is a non-blocking assignment. That is it makes a temporary copy of the righthand side carries on procedurally (non-blocking) executing the code for this timestep then makes the assignment from the temp variable to the left hand side. It is used to model the simulation of flip-flop behaviour.

A flip-flop can only change value once per clock cycle.

You have (simplified code):

out_sig_q_reg[dstVal] <= 0;
for (i=0; i<2; i=i+1) begin
  for (j=0; j<8; j=j+1) begin
    out_sig_q_reg[dstVal] <= out_sig_q_reg[dstVal] + tap_output_q[i][dstVal][j];
  end
end

In the above code out_sig_q_reg[dstVal] <= 0; will never take effect it is always overridden by the next statement; out_sig_q_reg[dstVal] <= out_sig_q_reg[dstVal] ...

Your for loop repeatedly uses the same left hand side, but only the last assignment will win. For a given register only one <= per clockcycle can be effective. Effective for-loops would need to change the inner most left-hand register.

You could create a combinatorial block which describes the iteration using = and then put it through one flip-flop at the end.

always @* begin
   //..
   out_sig_q[dstVal] = 0;
   for (i=0; i<2; i=i+1) begin
     for (j=0; j<8; j=j+1) begin
       out_sig_q[dstVal] = out_sig_q[dstVal] + tap_output_q[i][dstVal][j];
     end
   end
   //..
 end

always (@posedge clk) begin 
  for ...
    out_sig_q_reg[dstVal] <= out_sig_q[dstVal];
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the quick response. So are you putting both of those always blocks within a single larger: for (dstVal=0; dstVal<2; dstVal=dstVal+1) ?
@toozie21 No, you will have to put that inside each always block. It is not common to have always inside for, as that becomes a generate for-loop. I added the //.. as a cryptic guide for you to fillin the loop details.
Hmm, doesn't seem to like it. I have "always @* begin" followed by "for (dstVal=0; dstVal<2; dstVal=dstVal+1)" followed by "out_sig_q[dstVal] = 0;". but that throws a "Procedural assignment to a non-register out_sig_q is not permitted, left-hand side should be reg/integer/time/genvar" error.
@toozie21 out_sig_q would also need to be declared as a reg type, but it is not a flip-flop.
use reg for always,initial. wire for assign and connecting instance outputs.

Your Answer

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.