我正在使用Verilog设计类似MIPS的CPU,现在正在处理数据危害。
我有这些指示:
Ins[0] = LW r1 r0(100)
Ins[1] = LW r2 r0(101)
Ins[2] = ADD r3 r2 r1
我正在使用管道,而我的dataPath是这样的:
我有5个阶段,有4个闩锁缓冲区将它们分开。
问题是,当ADD指令到达stage3(ALU应该在其中计算r1 + r2)时,指令1(第二个LW)在阶段4中,并且尚未读取存储器的r0 + 101地址,因此我应该暂停一个周期,然后Ins1到达最后一个阶段。
在这种情况下,第一个LW已完成工作,并且r1的新值不在dataPath中的任何位置,但我需要将此值传递给ALU的输入B。
(这被称为数据转发,因为当第三条指令处于阶段2时,r1的值尚未准备好,我应该从后面的阶段转发它(蓝色的线从最后的MUX发出并进入ALU MUX),但是因为第二个LW的失速状态,我再也没有r1的值了。
谢谢你的帮助。
最佳答案
我犯了一个错误。我的错误是,当LType指令跟随LDM指令时,我会在Rtype处于stage3而LDM处于stage4时停止处理器。但是相反,当RType在stage2(解码)而LDM在stage3(exec)时,我应该在此之前的一个时钟检测到依赖性。
在这种情况下,我应该暂停管道。
因此,当Rtype在阶段2,第二个LDM在阶段3,第一个LDM在阶段4时,我检测到相关性并停滞管道一个周期。
因此,在下一个时钟中,Rtype仍在stage2中,第二个LDM在stage4中,第一个LDM正在写回寄存器,因此由于RType仍在stage2中,它可以读取写入寄存器文件的数据。 (写回操作在时钟忽略时完成。在posege中,RType的第一个参数已准备好。)