MIPS处理器中的偏见:R型指令与I型指令

此博客为个人博客,不涉及商业用途,仅提供学习参考,内容均来自个人原创以及互联网转载和摘录。
此博客上带有原创标识的文章、图片、文件等,未经本人允许,不得用于商业用途以及传统媒体。
本文首发于CSDN,其他网站均为转载。网络媒体或个人转载请注明出处和链接,否则属于侵权行为。

原博客链接:https://blog.csdn.net/qq_38305370
原博主昵称:城外南风起
————————————————

MIPS指令分为R型、I型和J型,这里不讨论J型(后面可能会补)。R型指令比I型指令常见,这就导致在设计处理器时,默认实现R型指令,只有当检测到I型指令时,才做调整。即对I型指令有偏见,优先照顾R型指令。

R型字段:

在这里插入图片描述
I型字段:

在这里插入图片描述
可以看到,R型和I型共同拥有的字段为op、rs、rt。其中rt在I型指令中为目标寄存器地址,而在R型指令中为源操作数寄存器地址。R型指令的目标寄存器地为rd。所以,在告诉执行阶段目标寄存器地址时,默认告诉其rd,即[15:11]位;只有检测到I型指令时,才修改为rt,即[20:16]位。

那么,是如何检测I型指令的呢?

根据op确定指令类型,就能确定目标寄存器地址是取rt(I型)还是rd(R型)。

以ori指令译码为例:

	//acquire fields
	//note rd, shamt and funct only exist in R-type and I-type instruction
	wire [5:0] op = inst_i[31:26];
	wire [5:0] rs = inst_i[25:21];
	wire [5:0] rt = inst_i[20:16];
	wire [5:0] rd = inst_i[15:11];
	wire [4:0] shamt = inst_i[10:6];
	wire [5:0] funct = inst_i[5:0];
	wire [15:0] imm_value = inst_i[15:0];

	//save extended immediate
	reg [`RegBus] imm;

	//instruction valid
	reg instvalid;
	/*						decode						*/
	always @ (*) begin
		if(rst == `RstEnable) begin
			aluop_o <= `EXE_NOP_OP;
			alusel_o <= `EXE_RES_NOP;
			waddr_o <= `NOPRegAddr;
			wreg_o <= `WriteDisable;
			instvalid <= `InstValid;
			re1_o <= `ReadDisable;
			re2_o <= `ReadDisable;
			raddr1_o <= `NOPRegAddr;
			raddr2_o <= `NOPRegAddr;
			imm <= `ZeroWord;
		end
		else begin
			aluop_o <= `EXE_NOP_OP;
			alusel_o <= `EXE_RES_NOP;
			waddr_o <= rd;	//default R-type
			wreg_o <= `WriteDisable;
			instvalid <= `InstValid;
			re1_o <= `ReadDisable;
			re2_o <= `ReadDisable;
			raddr1_o <= rs;
			raddr2_o <= rt;
			imm <= `ZeroWord;
		end		

		case(op)
			`EXE_ORI: begin //determine whether or not it is an ori instruction by op
				we <= `WriteEnable; //result after ori should be written into regfile
				alusel_o <= `EXE_OR_OP; //or operation
				alusel_sel <= `EXE_RES_LOGIC; //logic operation
				re1_o <= `ReadEnable;	//read port 1
				re2_o <= `ReadDisable;	//not read port 2
				imm <= {16'h0, imm_value}//extend immediate
				waddr_o <= rt; //I-type
				instvalid <= `InstValid;				
			end
			default: begin				
			end
		endcase
	end

复位后目标寄存器地址默认为rd(R型),即waddr_o <= rd。当检测到ori指令后,再修改为rt(I型),即waddr_o <= rt。

与此同时,还会对寄存器堆栈中的两个读端口使能信号进行修改。I型指令只读取一个端口(只有一个源操作数),另一个输出给执行阶段的操作数为扩展后的立即数(imm),实现代码如下:

	/*						determine source operand 1						*/
	always @ (*) begin
		if(rst == `RstEnable) begin
			op_reg1_o <= `ZeroWord;
		end
		else if(re1 == `ReadEnable) begin
			op_reg1_o <= rdata1_i;
		end
		else if(re1 == `ReadDisable) begin 	//use immediate if not read register
			op_reg1_o <= imm;
		end
		else begin
			op_reg1_o <= `ZeroWord;
		end
	end 
	/*						determine source operand 1						*/
	always @ (*) begin
		if(rst == `RstEnable) begin
			op_reg2_o <= `ZeroWord;
		end
		else if(re2 == `ReadEnable) begin
			op_reg2_o <= rdata2_i;
		end
		else if(re2 == `ReadDisable) begin 	//use immediate if not read register
			op_reg2_o <= imm;
		end
		else begin
			op_reg2_o <= `ZeroWord;
		end
	end 

参考:
1.雷思磊著.自己动手写CPU[M].电子工业出版社,2014.
2.(美)帕特森,(美)亨尼斯著.计算机组成与设计 硬件/软件接口 原书第5版[M].机械工业出版社,2015.
————————————————
感谢您的阅读,如果您有收获,请给我一个三连吧!
如果您觉得这还不够,可以点击 打赏 按钮,告诉我: 你币有了!

你可能感兴趣的:(计算机组成与设计,mips,cpu,verilog,芯片)