Verilog的流水线设计问题

虚空之星

我刚开始学习Verilog,因为我购买了FPGA。由于我还没有FPGA,因此我开始了一个比较大的项目,只是想知道我要去哪里。我可能对此一无所知,但我正在尝试制作一个简单的流水线CORDIC模块。我在模拟这里遇到的问题是,值将从测试平台的输入传播到UUT,被测单元,CORDIC旋转器的实例,这些信号传播到第一阶段的管道,xpipe[0]ypipe[0]zpipe[0],然后到一个cordic_stage实例,但这种的输出cordic_stage情况似乎并不在被更改任何值xpipe[1]ypipe[1]zpipe[1]寄存器,它们保持在zzzz现在,我确定这里的模块有100万个错误,但我想自行解决。我想知道的是为什么这些值不能将其从cordic_stage管道的数组中移到下一个元素中,以及如何修复它。这是我的代码如下:

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
提姆

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章