Verilog如何展开嵌套for循环?

too*_*e21 0 for-loop verilog fpga

我试图用一系列嵌套for循环做一个累积和,我没有运气.我想我需要更好地理解Verilog如何展开for循环才能真正想象出如何解决我的问题.

基本上我有一系列的tap输出(tap_output_i和tap_output_q)是3D阵列(src,dst,tap).我想总结每个时钟到达特定目的地的所有源和抽头.

这是我有的不起作用(每次out_sig为0):

//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];
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是重置每个计数的累计(out_sig_i_regout_sig_q_reg)总和...

Mor*_*gan 5

<=是一个非阻塞任务.也就是说,它使得右侧的临时副本在程序上执行(非阻塞)执行此时间步的代码,然后从temp变量到左侧进行赋值.它用于模拟触发器行为的模拟.

触发器每个时钟周期只能改变一次值.

你有(简化代码):

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
Run Code Online (Sandbox Code Playgroud)

在上面的代码out_sig_q_reg[dstVal] <= 0;将永远不会生效它始终被下一个语句覆盖;out_sig_q_reg[dstVal] <= out_sig_q_reg[dstVal] ...

你的for循环重复使用相同的左手边,但只有最后一个分配才会获胜.对于给定的寄存器,<=每个时钟周期只有一个有效.有效的for循环需要改变最左边的内部寄存器.

您可以创建一个组合块来描述使用的迭代=,然后在最后通过一个触发器.

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];
Run Code Online (Sandbox Code Playgroud)