移动操作指令的实现

均为R指令,靠func功能码判断
在这里插入图片描述
在这里插入图片描述
movn和movz实现很常规,执行时只需要多加个判断0
在这里插入图片描述
2的写HI、LO均在回写阶段;不写通用寄存器,所以wreg_o为disable,wd_o为0(这儿好像就明白了为什么$0一直为0)
3则需要写通用寄存器
在这里插入图片描述
需增加2个寄存器、执行阶段增加一个mux应对读HILO的指令、并处理新的数据相关
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

`include "defines.v"

module hilo_reg(

	input wire					  clk,
	input wire					  rst,
	
	//写端口
	input wire					  we,
	input wire[`RegBus]			     hi_i,
	input wire[`RegBus]			  lo_i,
	
	//读端口1
	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 <= hi_i;
			lo_o <= lo_i;
		end
	end

endmodule

在这里插入图片描述

								`EXE_MFHI: begin	//NEW
									wreg_o <= `WriteEnable;		aluop_o <= `EXE_MFHI_OP;
									alusel_o <= `EXE_RES_MOVE;   reg1_read_o <= 1'b0;	reg2_read_o <= 1'b0;
									instvalid <= `InstValid;	
								end
								`EXE_MFLO: begin
									wreg_o <= `WriteEnable;		aluop_o <= `EXE_MFLO_OP;
									alusel_o <= `EXE_RES_MOVE;   reg1_read_o <= 1'b0;	reg2_read_o <= 1'b0;
									instvalid <= `InstValid;	
								end
								`EXE_MTHI: begin
									wreg_o <= `WriteDisable;		aluop_o <= `EXE_MTHI_OP;
									reg1_read_o <= 1'b1;	reg2_read_o <= 1'b0; instvalid <= `InstValid;	
								end
								`EXE_MTLO: begin
									wreg_o <= `WriteDisable;		aluop_o <= `EXE_MTLO_OP;
									reg1_read_o <= 1'b1;	reg2_read_o <= 1'b0; instvalid <= `InstValid;	
								end
								`EXE_MOVN: begin	
									aluop_o <= `EXE_MOVN_OP;
									alusel_o <= `EXE_RES_MOVE;   reg1_read_o <= 1'b1;	reg2_read_o <= 1'b1;
									instvalid <= `InstValid;
								 	if(reg2_o != `ZeroWord) begin
	 									wreg_o <= `WriteEnable;
	 								end 
									else begin
	 									wreg_o <= `WriteDisable;
	 								end
								end
								`EXE_MOVZ: begin	//NEW
									aluop_o <= `EXE_MOVZ_OP;
									alusel_o <= `EXE_RES_MOVE;   reg1_read_o <= 1'b1;	reg2_read_o <= 1'b1;
									instvalid <= `InstValid;
								 	if(reg2_o == `ZeroWord) begin
	 									wreg_o <= `WriteEnable;
	 								end 
									else begin
	 									wreg_o <= `WriteDisable;
	 								end		  							
								end

在这里插入图片描述
在这里插入图片描述

`include "defines.v"

module ex(

	input wire					  		rst,
	
	//送到执行阶段的信息
	input wire[`AluOpBus]         aluop_i,
	input wire[`AluSelBus]        alusel_i,
	input wire[`RegBus]           reg1_i,
	input wire[`RegBus]           reg2_i,
	input wire[`RegAddrBus]       wd_i,
	input wire                    wreg_i,

	//HI、LO寄存器的值	赋值给通用寄存器
	input wire[`RegBus]           hi_i,
	input wire[`RegBus]           lo_i,

	//回写阶段的指令是否要写HI、LO,用于检测HI、LO的数据相关
	input wire[`RegBus]           wb_hi_i,
	input wire[`RegBus]           wb_lo_i,
	input wire                    wb_whilo_i,
	
	//访存阶段的指令是否要写HI、LO,用于检测HI、LO的数据相关
	input wire[`RegBus]           mem_hi_i,
	input wire[`RegBus]           mem_lo_i,
	input wire                    mem_whilo_i,
	
	//执行结果
	output reg[`RegAddrBus]       wd_o,
	output reg                    wreg_o,
	output reg[`RegBus]			   wdata_o,
	
	//执行阶段的指令对HI、LO寄存器的写操作请求 通用寄存器赋值给HILO
	output reg[`RegBus]           hi_o,
	output reg[`RegBus]           lo_o,
	output reg                    whilo_o		
);
	//保存逻辑运算的结果
	reg[`RegBus] logicout;	//保存逻辑运算结果
	reg[`RegBus] shiftres;	//保存移位运算结果
	reg[`RegBus] moveres;	//保存移动操作结果
	reg[`RegBus] HI;			//保存HI最新值
	reg[`RegBus] LO;			//保存LO最新值
	
	
	//根据大类型判断输出
   always @ (*) begin
 	   wd_o   <= wd_i;		//传递写目的寄存器地址	 	 	
 	   wreg_o <= wreg_i;		//传递寄存器写使能信号
 	   case ( alusel_i ) 
 	   	`EXE_RES_LOGIC:	begin
 	   		wdata_o <= logicout;
 	   	end
			`EXE_RES_SHIFT:		begin
				wdata_o <= shiftres;
			end	 			
			`EXE_RES_MOVE:		begin	//移动操作指令的alusel_i
				wdata_o <= moveres;
			end	  	   	
			default: begin
 	   		wdata_o <= `ZeroWord;
 	   	end
 	   endcase
   end	
	
	//根据小类型作逻辑运算
	always @ (*) 
		if(rst == `RstEnable) begin
			logicout <= `ZeroWord;
		end 
		else begin
			case (aluop_i)
				`EXE_OR_OP:			begin
					logicout <= reg1_i | reg2_i;
				end
				`EXE_AND_OP:		begin
					logicout <= reg1_i & reg2_i;
				end
				`EXE_NOR_OP:		begin
					logicout <= ~(reg1_i |reg2_i);
				end
				`EXE_XOR_OP:		begin
					logicout <= reg1_i ^ reg2_i;
				end
				default:			begin
					logicout <= `ZeroWord;
				end
			endcase
		end    
		
	//根据小类型作移位运算
	always @ (*) 
		if(rst == `RstEnable) begin
			shiftres <= `ZeroWord;
		end 
		else begin
			case (aluop_i)
				`EXE_SLL_OP:		begin
					shiftres <= reg2_i << reg1_i[4:0] ;
				end
				`EXE_SRL_OP:		begin
					shiftres <= reg2_i >> reg1_i[4:0];
				end
				`EXE_SRA_OP:		begin	//sra和srav都是这个指令
					shiftres <= ({32{reg2_i[31]}} << (6'd32-{1'b0, reg1_i[4:0]})) 
												| reg2_i >> reg1_i[4:0];
				end
				default:				begin
					shiftres <= `ZeroWord;
				end
			endcase
		end 

	//MFHI、MFLO、MOVN、MOVZ指令 移动操作
	always @ (*) begin
		if(rst == `RstEnable) begin
			moveres <= `ZeroWord;
	   end 
		else begin
			moveres <= `ZeroWord;
			case (aluop_i)
				`EXE_MFHI_OP:		begin	//将HI的值作为移动操作的结果
					moveres <= HI;
				end
				`EXE_MFLO_OP:		begin	//将LO的值作为移动操作的结果
					moveres <= LO;
				end
				`EXE_MOVZ_OP:		begin	//将reg1_i的值作为移动操作的结果
					moveres <= reg1_i;
				end
				`EXE_MOVN_OP:		begin	//将reg1_i的值作为移动操作的结果
					moveres <= reg1_i;
				end
				default : begin
				end
			endcase
	  end
	end	 

  //得到最新的HI、LO寄存器的值,此处要解决指令数据相关问题
	always @ (*) begin
		if(rst == `RstEnable) begin
			{HI,LO} <= {`ZeroWord,`ZeroWord};
		end 
		else if(mem_whilo_i == `WriteEnable) begin
			{HI,LO} <= {mem_hi_i,mem_lo_i};
		end 
		else if(wb_whilo_i == `WriteEnable) begin
			{HI,LO} <= {wb_hi_i,wb_lo_i};
		end 
		else begin
			{HI,LO} <= {hi_i,lo_i};			
		end
	end	

	//如果是MTHI MTLO 则需要给出whilo_o、hi_o、lo_o值
	always @ (*) begin
		if(rst == `RstEnable) begin
			whilo_o <= `WriteDisable;
			hi_o <= `ZeroWord;
			lo_o <= `ZeroWord;		
		end 
		else if(aluop_i == `EXE_MTHI_OP) begin
			whilo_o <= `WriteEnable;
			hi_o <= reg1_i;
			lo_o <= LO;
		end 
		else if(aluop_i == `EXE_MTLO_OP) begin
			whilo_o <= `WriteEnable;
			hi_o <= HI;
			lo_o <= reg1_i;
		end 
		else begin
			whilo_o <= `WriteDisable;
			hi_o <= `ZeroWord;
			lo_o <= `ZeroWord;
		end				
	end	

endmodule

在这里插入图片描述
在这里插入图片描述

`include "defines.v"

module ex_mem(

	input wire					 clk,
	input wire					 rst,
	
	
	//来自执行阶段的信息	
	input wire[`RegAddrBus]      ex_wd,
	input wire                   ex_wreg,
	input wire[`RegBus]			 ex_wdata, 	
	input wire[`RegBus]          ex_hi,      //NEW
	input wire[`RegBus]          ex_lo,      //NEW
	input wire                   ex_whilo, 	 //NEW
	
	//送到访存阶段的信息
	output reg[`RegAddrBus]      mem_wd,
	output reg                   mem_wreg,
	output reg[`RegBus]			 mem_wdata,
	output reg[`RegBus]          mem_hi,     //NEW
	output reg[`RegBus]          mem_lo,     //NEW
	output reg                   mem_whilo	 //NEW
	
	
);

	always @ (posedge clk) begin
		if(rst == `RstEnable) begin
			mem_wd <= `NOPRegAddr;
			mem_wreg <= `WriteDisable;
		    mem_wdata <= `ZeroWord;	
		    mem_hi <= `ZeroWord;
		    mem_lo <= `ZeroWord;
		    mem_whilo <= `WriteDisable;		  
		end else begin
			mem_wd <= ex_wd;
			mem_wreg <= ex_wreg;
			mem_wdata <= ex_wdata;	
			mem_hi <= ex_hi;
			mem_lo <= ex_lo;
			mem_whilo <= ex_whilo;					
		end  
	end      
			
endmodule

在这里插入图片描述

`include "defines.v"

module mem(

	input wire						rst,
	
	//来自执行阶段的信息	
	input wire[`RegAddrBus]       wd_i,
	input wire                    wreg_i,
	input wire[`RegBus]					  wdata_i,
	input wire[`RegBus]           hi_i,
	input wire[`RegBus]           lo_i,
	input wire                    whilo_i,	
	
	//送到回写阶段的信息
	output reg[`RegAddrBus]      wd_o,
	output reg                   wreg_o,
	output reg[`RegBus]					 wdata_o,
	output reg[`RegBus]          hi_o,
	output reg[`RegBus]          lo_o,
	output reg                   whilo_o	
	
);

	
	always @ (*) begin
		if(rst == `RstEnable) begin
			wd_o <= `NOPRegAddr;
			wreg_o <= `WriteDisable;
		  wdata_o <= `ZeroWord;
		  hi_o <= `ZeroWord;
		  lo_o <= `ZeroWord;
		  whilo_o <= `WriteDisable;		  
		end else begin
		  wd_o <= wd_i;
			wreg_o <= wreg_i;
			wdata_o <= wdata_i;
			hi_o <= hi_i;
			lo_o <= lo_i;
			whilo_o <= whilo_i;			
		end  
	end      
			

endmodule

在这里插入图片描述

`include "defines.v"

module mem_wb(

	input	wire				  clk,
	input wire				      rst,
	

	//来自访存阶段的信息	
	input wire[`RegAddrBus]       mem_wd,
	input wire                    mem_wreg,
	input wire[`RegBus]			 mem_wdata,
	input wire[`RegBus]           mem_hi,
	input wire[`RegBus]           mem_lo,
	input wire                    mem_whilo,	

	//送到回写阶段的信息
	output reg[`RegAddrBus]      wb_wd,
	output reg                   wb_wreg,
	output reg[`RegBus]			 wb_wdata,
	output reg[`RegBus]          wb_hi,
	output reg[`RegBus]          wb_lo,
	output reg                   wb_whilo		       
	
);


	always @ (posedge clk) begin
		if(rst == `RstEnable) begin
			wb_wd <= `NOPRegAddr;
			wb_wreg <= `WriteDisable;
		  wb_wdata <= `ZeroWord;	
		  wb_hi <= `ZeroWord;
		  wb_lo <= `ZeroWord;
		  wb_whilo <= `WriteDisable;		  
		end else begin
			wb_wd <= mem_wd;
			wb_wreg <= mem_wreg;
			wb_wdata <= mem_wdata;
			wb_hi <= mem_hi;
			wb_lo <= mem_lo;
			wb_whilo <= mem_whilo;			
		end  
	end      
			

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值