Verilog多级管道缓冲区问题

时间:2018-11-30 00:33:26

标签: verilog

我正在为Verilog HDL中的2级管道处理器开发一个学校项目,但遇到了一个困扰我几天的问题。我将通过我的描述添加小代码段和通过ModelSim获得的信号图片。我只是从ALU中获取输出:

ALU #(BUS_WIDTH(BUS_WIDTH)) alu (
    .A(Amux),
    .B(Bmux),
    .sel(ALUsel),
    .Dout(ALUout)
);

然后,我以以下方式将其直接传递到同一文件中各阶段之间的缓冲区(为了便于阅读,其他信号和数据被缓冲了):

Buffer #(.BUS_WIDTH(BUS_WIDTH)) buff(
    .clk(clk),
    .reset(reset),
    .aluA(ALUout),
    .aluB(ALUoutM),
);

缓冲模块的内部如下所示(为了便于阅读,我再次删除了正在缓冲的所有其他内容:

module Buffer(
    input clk,
    input reset,
    input [31:0] aluA,
    output reg [31:0] aluB
);

    always @(posedge clk)
    begin
        if (~reset)
        begin
            aluB <= 32'h00000000;
        end else
        begin
            aluB <= aluA;
        end
    end
endmodule

以下图片是我遇到的问题:enter image description here

这是在启动测试台并成功运行之前的几个周期后发生的。看图像,顶部信号是ALUout,第二个信号是ALUoutM。我希望得到的结果是使我的ALUoutM信号与上一个时钟周期的ALUout信号相匹配(我已经验证了完整的时钟周期是图像中信号变化之间的周期)。如前所述,在此周期之前的所有周期中都可以看到这种期望的结果。在第一个周期和第二个周期之间,结果并不理想,但随后又恢复了正确性。我已经三重检查并确认我的ALUoutM不受任何其他信号驱动。我主要是想弄清楚我是否在使用Verilog犯了一个我不知道的初学者错误。感谢您的任何帮助。

添加

根据Oldfart的评论(我喜欢这个名字),我也能够将缓冲区的信号添加到模拟器中,但是它显示的行为与输入信号完全相同。在下图中,您会注意到前4个时钟周期的行为正确,然后缓冲区中出现了一个随机值0x00000000。然后在完全脱离轨道之前再经过一个时钟周期是正确的。

enter image description here

1 个答案:

答案 0 :(得分:0)

好的,感谢奥尔德法特(Oldfart)(仍然喜欢这个名字)给了我有关该问题的建议。在与教授和助教讨论完所有内容后,我更改了所有MUX,以在

上触发

always @ ( * )

发布问题时没有想到的

信号。我以前将它们创建为

always @ (sel or input_a or input_b or ... or input_N)

并没有像预期的MUX那样立即传播我的数据。我相信这是因为所有输入都不会同时到达MUX,从而导致输出值可能会更改与更改的信号数量相同的次数(除非您很幸运地每个信号都同时到达)。在所有输入都传播到MUX之前,这可能多次给您错误的信号。简而言之,如果您按照我原来的方式进行操作,谁知道您最终将获得什么价值。

这与将我的输出“注册”到我的模块一起解决了我的问题。对于不确定我意思的人,当我声明输出时,我这样做

output reg [(width - 1):0] output_x

相对于

output [(width - 1):0] output_x

我不是100%地确定为什么这样做会有所帮助,但是当我回去执行此操作时,它使整个处理器给我的信号更好,达到了我的预期。我相信这是因为它导致所有输出“闩锁”。如果有人能详细说明为什么这样做会有帮助,我将不胜感激。