代码放在github上
在之前实现的基础上继续增加了移动操作指令(增加了特殊寄存器HI和LO,以及对他们的操作)
之前操作的传送门:
单指令周期ori指令的实现
单指令周期CPU—–逻辑、移位操作和空指令
指令简介
MIPS指令集架构中定义6条移动操作指令:movn、movz、mfhi、mthi、mflo、mtlo
后4条指令涉及对特殊寄存器HI、LO的读写操作
HI、LO寄存器用于保存乘法、除法结果
6条移动操作指令格式:
由指令格式可以看出指令码都是6’b000000(bit26\~31),由功能码(0\~5bit)判断是哪个指令,并且指令6~10bit都是0
- movn(功能码是6’b001011):用法:movn rd, rs, rt;作用:if rt != 0 then rd <- rs(如果rt通用寄存器里的值不为0,则将地址为rs的通用寄存器的值赋值给地址为rd的通用寄存器)
- movz(功能码是6’b001010):用法:movn rd, rs, rt;作用:if rt == 0 then rd <- rs(如果rt通用寄存器里的值为0,则将地址为rs的通用寄存器的值赋值给地址为rd的通用寄存器)
- mfhi(功能码是6’b010010):用法:mflo rd 作用:rd <- lo将特殊寄存器HI的值赋给地址为rd的通用寄存器
- mflo(功能码是6’b010000):用法 mflo rd 作用:rd <- lo将特殊寄存器LO的值赋给地址为rd的通用寄存器
- mthi(功能码是6‘b010001):用法:mthi rs 作用:hi <- rs将地址为rs的通用寄存器的值赋给特殊寄存器HI
- mtlo(功能码是6’b010011):用法:mtlo rs 作用:lo <- rs,将地址为rs的通用寄存器的值赋给特殊寄存器LO
修改系统结构
对之前的结构进行改变
1. 增加HILO模块,实现HI、LO寄存器
2. 增加执行模块EX的输入接口,接收从HILO模块传来的HI、LO寄存器的值;输出到WB模块是否要写HILO、写入HI寄存器的值、写入LO寄存器的值
3. 增加回写模块WB的输入输出接口
添加HILO模块,实现HI、LO寄存器
module hilo_reg(
input wire clk,
input wire rst,
//写端口
input wire we,
input wire[`RegBus] hi_i,
input wire[`RegBus] lo_i,
//读端口
output reg[`RegBus] hi_o,
output reg[`RegBus] lo_o
);
always @(posedge clk)begin
if(rst==`RstEnable) begin
hi_o <= `ZeroWord;
lo_o <= `ZeroWord;
end else if(we == `WriteEnable) begin
hi_o<=
end
end
修改译码阶段的ID模块
首先把移动操作这令的这六条指令的功能码和操作码以及操作类型的宏定义添加到defines.v文件中去:
`define EXE_MOVZ 6'b001010 //指令MOVZ的功能码
`define EXE_MOVN 6'b001011 //指令MOVN的功能码
`define EXE_MFHI 6'b010000 //指令MFHI的功能码
`define EXE_MTHI 6'b010001 //指令MTHI的功能码
`define EXE_MFLO 6'b010010 //指令MFLO的功能码
`define EXE_MTLO 6'b010011 //指令MTLO的功能码
`define EXE_MOVZ_OP 8'b00001010
`define EXE_MOVN_OP 8'b00001011
`define EXE_MFHI_OP 8'b00010000
`define EXE_MTHI_OP 8'b00010001
`define EXE_MFLO_OP 8'b00010010
`define EXE_MTLO_OP 8'b00010011
`define EXE_RES_MOVE 3'b011
其次在译码模块ID中根据六条指令的功能码判断是那一条指令:
- MFLO和MFHI:将特殊寄存器LO和HI赋给通用寄存器,则可以知道肯定是要修改寄存器的即wreg_o为WriteEnable,而且不需要读取寄存器的值即reg1_read_o和reg2_read_o都为0,另外运算类型为
EXE_RES_MOVE
- MTHI和MTLO:将通用寄存器的值赋值给特殊寄存器LO和HI,则可知不需要修改通用寄存器的值即wreg_o为WriteDisable,需要读取端口1的寄存器的值,也就是指令中rs的值即reg1_read_o 为1,另外运算类型为
EXE_RES_NOP
- MOVN和MOVZ:需要读取rs,rt寄存器的值即reg1_read_o和reg2_read_o都为1,从端口1中读取rs寄存器(指令的21\~25b