2013-11-26 40 views
1

我剛開始學習Verilog,因爲我購買了FPGA。由於我還沒有我的FPGA,我開始了一個有點大的項目,只是爲了看看我的位置。我可能會咬掉更多,但我試圖製作一個簡單的流水線CORDIC模塊。我在這裏模擬的問題是,數值將從測試臺的輸入傳播到被測單元(漩渦旋轉器的一個實例),這些信號傳播到流水線中的第一個階段,即xpipe[0],ypipe[0],zpipe[0],然後到一個cordic_stage實例,但這個實例cordic_stage的輸出似乎沒有在xpipe[1]ypipe[1],或zpipe[1]寄存器被改變的任何值,但它們仍然在zzzz。現在我確信在這裏我的模塊有一百萬和一個錯誤,但我想要自己弄清楚它們。我想知道的是爲什麼這些值不會將cordic_stage排除在流水線陣列中的下一個元素之外,以及我如何修復它。這裏是我下面的代碼:Verilog流水線設計問題

module cordic_stage #(
    parameter ANGLE_WIDTH = 16, 
    parameter VALUE_WIDTH = 8, 
    parameter STAGE_I = 0 
    )(
    input clk, 
    input [VALUE_WIDTH-1:0] xin, 
    input [VALUE_WIDTH-1:0] yin, 
    input [ANGLE_WIDTH-1:0] zin, 
    output reg [VALUE_WIDTH-1:0] xout, 
    output reg [VALUE_WIDTH-1:0] yout, 
    output reg [ANGLE_WIDTH-1:0] zout 
    ); 
    parameter DELTA = 1 << (ANGLE_WIDTH - 2); 
    always @(posedge clk) begin 
     if (zin[ANGLE_WIDTH-1]) begin 
      xout <= xin + (yin >> STAGE_I); // These assignments to outputs are WORKING 
      yout <= yout - (xin >> STAGE_I); 
      zout <= zin + (DELTA >> STAGE_I); 
     end else begin 
      xout <= xin - (yin >> STAGE_I); 
      yout <= yout + (xin >> STAGE_I); 
      zout <= zin - (DELTA >> STAGE_I); 
     end 
    end 
endmodule 

module cordic_rotator #(
    parameter ANGLE_WIDTH = 16, 
    parameter VALUE_WIDTH = 8 
    )(
    input clk, 
    input [ANGLE_WIDTH-1:0] angle, 
    input [VALUE_WIDTH-1:0] xin, 
    input [VALUE_WIDTH-1:0] yin, 
    output [VALUE_WIDTH-1:0] xout, 
    output [VALUE_WIDTH-1:0] yout 
    ); 
    reg [VALUE_WIDTH-1:0] xpipe [ANGLE_WIDTH:0]; // The second element in these pipelines arrays at index 1 never gets changed, so that it NOT WORKING 
    reg [VALUE_WIDTH-1:0] ypipe [ANGLE_WIDTH:0]; 
    reg [ANGLE_WIDTH-2:0] zpipe [ANGLE_WIDTH:0]; 
    always @(*) begin 
     xpipe[0] <= angle[ANGLE_WIDTH-1] ? -xin : xin; // These assignments to the first element in the pipeline are WORKING 
     ypipe[0] <= angle[ANGLE_WIDTH-1] ? -yin : yin; 
     zpipe[0] <= angle[ANGLE_WIDTH-2:0]; 
    end 
    genvar i; 
    generate 
     for (i = 0; i < ANGLE_WIDTH; i = i + 1) begin: stages 
      cordic_stage #(ANGLE_WIDTH-1, VALUE_WIDTH, i) stage(clk, xpipe[i], ypipe[i], zpipe[i], xpipe[i+1], ypipe[i+1], zpipe[i+1]); // Values are being passed from the first stage in the pipeline at index zero to the first cordic_stage module, so that is WORKING 
     end 
    endgenerate 
endmodule 

module cordic_rotator_testbench; 

    // Inputs 
    reg clk; 
    reg [3:0] angle; 
    reg [3:0] xin; 
    reg [3:0] yin; 

    // Outputs 
    wire [3:0] xout; 
    wire [3:0] yout; 

    // Instantiate the Unit Under Test (UUT) 
    cordic_rotator #(4,4) uut (
     .clk(clk), 
     .angle(angle), 
     .xin(xin), 
     .yin(yin), 
     .xout(xout), 
     .yout(yout) 
    ); 

    initial begin 
     // Initialize Inputs 
     clk = 0; 
     angle = 0; 
     xin = 0; 
     yin = 0; 

     // Wait 100 ns for global reset to finish 
     #100; 

     // Add stimulus here 

     assign angle = 2; // These lines are also WORKING 
     assign xin = 8; 
     assign yin = 0; 

    end 

    always #5 clk = !clk; 

endmodule 
+0

如果你把答案放在答案中,我可以給你你應得的代表。我發現我的設計存在更多問題,但解決了我的管道問題。 –

+0

謝謝,我已經這麼做了。不知道爲什麼你沒有在你的情況下得到編譯錯誤,但很高興它有幫助。 – Tim

回答

1

你開着寄存器xpipe,直接從一個模塊,我還以爲這將是一個語法錯誤的輸出線,爲寄存器類型只應該在被驅動程序塊。

您可能會嘗試將xyzpipe類型從reg更改爲wire,因爲導線類型是應該由模塊輸出驅動的。

OP的附錄: cordic_rotator中的代碼針對導線類型進行了更改,這解決了問題。

wire [VALUE_WIDTH-1:0] xpipe [ANGLE_WIDTH:0]; 
wire [VALUE_WIDTH-1:0] ypipe [ANGLE_WIDTH:0]; 
wire [ANGLE_WIDTH-2:0] zpipe [ANGLE_WIDTH:0]; 
assign xpipe[0] = angle[ANGLE_WIDTH-1] ? -xin : xin; 
assign ypipe[0] = angle[ANGLE_WIDTH-1] ? -yin : yin; 
assign zpipe[0] = angle[ANGLE_WIDTH-2:0];