2015-02-05 1744 views
0

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

本质上,我有一系列抽头输出(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]; 

当我遇到问题时重置累计(out_sig_i_regout_sig_q_reg)和每一个个性化......

+0

是的,我使用out_sig_i_reg和out_sig_q_reg作为我cummultive总和。我无法弄清楚的是如何在求和之前每次累计求和并重置为零... – toozie21 2015-02-05 13:59:41

回答

5

<=是一个非阻塞赋值。这就是说,它使右侧的临时副本进行过程式(非阻塞式)执行此时间步骤的代码,然后将临时变量分配到左侧。它用于模拟触发器行为的模拟。

触发器每个时钟周期只能更改一次值。

你(简化代码):

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 

在上面的代码out_sig_q_reg[dstVal] <= 0;永远不会生效,它总是由下面的语句覆盖; out_sig_q_reg[dstVal] <= out_sig_q_reg[dstVal] ...

您的for循环重复使用相同的左侧,但只有最后一次分配才会胜出。对于给定的寄存器,每个时钟周期只能有一个<=有效。有效的for-loops将需要更改最内部的左侧寄存器。

您可以创建一个组合块,它使用=来描述迭代,然后在末尾通过一个触发器。

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]; 
+0

感谢您的快速响应。那么你是否把这两个总是在一个更大的块内:for(dstVal = 0; dstVal <2; dstVal = dstVal + 1)? – toozie21 2015-02-05 14:18:00

+0

@ toozie21不,你将不得不把它放在每个块中。它始终在内部并不常见,因为它变成了生成for-loop。我添加了'// ..'作为您隐藏循环细节的神秘指南。 – Morgan 2015-02-05 14:31:02

+0

嗯,似乎不喜欢它。我有“始终@ *开始”,后面跟着“for(dstVal = 0; dstVal <2; dstVal = dstVal + 1)”,后面跟着“out_sig_q [dstVal] = 0;”。但是会抛出“不允许使用程序分配给非注册out_sig_q,左侧应该是reg/integer/time/genvar”错误。 – toozie21 2015-02-05 14:55:26