2015-02-05 7 views
0

일련의 중첩 된 for 루프와 함께 누적 합계를 계산하려고하는데 행운이 없습니다. 내 문제를 해결하는 방법을 실제로 시각화하기 전에 Verilog가 for 루프를 어떻게 전개하는지 더 잘 이해해야한다고 생각합니다.Verilog는 for 중첩 된 for 루프를 어떻게 언로드합니까?

기본적으로 3D 배열 (src, dst, tap) 인 일련의 탭 출력 (tap_output_i 및 tap_output_q)이 있습니다. 나는 매 클럭마다 특정 소스로가는 모든 소스와 탭을 합치기를 원한다. ...

//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) 합계 모든 수를 누적를 재설정되어 문제로 실행하고 있습니다 : 여기

내가 그 (out_sig 때마다 0) 작동하지 않는 것을이다
+0

예, 전 out_sig_i_reg와 out_sig_q_reg를 내 cummultive 합계로 사용하고 있습니다. 내가 알아낼 수없는 것은 합계를 계산하기 전에 누적 합계를 계산하고 매번 0으로 재설정하는 방법입니다. – toozie21

답변

5

<=은 비 차단 할당입니다. 즉, 오른쪽 사이드의 임시 복사본을 절차 적으로 (비 차단)이 timestep에 대한 코드를 실행 한 다음 임시 변수에서 왼쪽으로 할당합니다. 플립 플롭 동작 시뮬레이션을 모델링하는 데 사용됩니다.

플립 플롭은 클럭주기마다 한 번만 값을 변경할 수 있습니다.

당신은 (간체 코드) 한 :

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 루프는 가장 안쪽에있는 가장 안쪽의 레지스터를 변경해야합니다.

=을 사용하여 반복을 설명하는 조합 블록을 만든 다음 끝에 하나의 플립 플롭으로 삽입 할 수 있습니다.

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

+0

@ toozie21 아니, 당신은 각각의 블록 내부에 넣어야 할 것입니다. for-loop를 생성하기 때문에 항상 내부에있는 것이 일반적이지 않습니다. 루프 세부 사항을 채우기위한 암호 가이드로'// .. '을 추가했습니다. – Morgan

+0

흠, 좋아하지 않는 것 같습니다. 나는 항상 "@ * 시작"다음에 "for (dstVal = 0; dstVal <2; dstVal = dstVal + 1)"다음에 "out_sig_q [dstVal] = 0;"이옵니다. 하지만 그것은 "등록되지 않은 out_sig_q에 대한 절차 적 할당은 허용되지 않습니다. 왼편은 reg/integer/time/genvar 여야합니다"오류가 발생합니다. – toozie21

관련 문제