这段代码太长了,所以我只描述它。我已经创建了一个几乎可以工作的5级mips管道。问题是到达指令解码级的每条lw指令都会覆盖执行级中的控制信号值。不仅如此,它还使PC跳过can指令,即从300 -> 308开始。我只是需要一些关于在哪里寻找bug的想法,因为这是一个类分配。如果我们去掉所有的LW指令,CPU就能正常工作。
示例: EX级中的加法器将小于$4 $1 $2,一旦LW进入ID级,则应为1。ALUsrc被断言,ALUop从减法改为加法。这迫使EX级中的加法器将$4 $1 $2相加,导致5被存储在$4中。
发布于 2012-01-18 09:22:13
http://en.wikipedia.org/wiki/File:MIPS_Architecture_%28Pipelined%29.svg

MIPS 5 Stage Pipeline (注释为显示写入寄存器选择并启用)
流水线阶段的底线表示寄存器堆写(回)端口地址和写使能,而WB是来自存储器的数据。
http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html
加载字指令描述:将一个字从指定地址加载到寄存器中。
运算:$t = MEM$s + offset;advance_pc (4);
语法: lw $t,offset($s)
编码: 1000 11ss ssst tttt iiii iiii
其中写入寄存器地址($t)输入是从由寄存器堆寄存器$s偏移量与立即值i组成的数据存储器地址读取的,该立即值i被符号扩展。你的$4是上面的$t,$1或$2是$s,而其余的寄存器文件输出通道听起来像是为扩展立即标志提供的。
从您的描述中,听起来您没有使用一个三端口的寄存器文件,其中一个端口是只写端口。
对于三端口寄存器堆,唯一遇到冲突的情况是在从存储器读取新的寄存器堆值并将其写入寄存器堆之前,尝试从内存使用新的寄存器堆值。这可以通过编译器调度NOOPs来管理,直到未完成的寄存器堆写入在后续指令尝试使用它时退出,或者当其输出包含对未完成寄存器堆写入的引用时在硬件中停止IF/ID。
IF/ID右边有三条指令,每条指令都有一个写寄存器堆地址和一个写使能。您需要将这两个指令解码寄存器堆地址与这三个地址进行比较,并停止IF/ID,直到这些地址被清空。存储在这三个流水线级中的每一个中的写使能被用来确定是否应该比较那些流水线级中的写寄存器地址。
由于ID/EX、EX/MEM和MEM/WB写入寄存器文件地址不在其他任何地方使用,因此用于进行比较的电路可以与IF/ID和寄存器文件并置,从而防止不必要的布局延迟影响最小时钟周期。
使用双端口寄存器文件要简单得多,并且可以推断/ID是否停止,直到写入使能从MEM/WB返回,从而有效地将任何内存读取指令转换为3周期指令(或者更多,如果是高速缓存或慢速,数据内存可能会停止)。出于性能原因,这使得三端口寄存器堆或多或少是必需的。当IF/ID停止(对于memory->regfile)时,MEM/WB阶段的两个寄存器堆端口控制(写使能、写地址)中至少有一个寄存器堆端口控制(写使能、写地址)需要使用隐含的多路复用器。
数据存储器访问可以停止MEM/WB,就像指令存储器访问也可以停止IF/ID一样。停止的IF/ID不会向ID/EX发出寄存器文件的写使能,停止的MEM/WB也不会。
https://stackoverflow.com/questions/8434743
复制相似问题