《自己动手写CPU》学习记录(9)——第7章/Part 2




目录

引言

致谢

流水线暂停

指令说明

madd、maddu、msub、msubu

设计

宏定义文件

程序计数器模块

译码模块

执行模块

访存模块

HI LO 寄存器模块

通用寄存器模块

流水线控制模块

程序ROM

MIPS32顶层

MIPS32 SOPC

仿真

仿真程序

TESTBENCH

仿真结果



引言

随章节进度继续推进,本章继续实现 乘加、乘减 指令等其他操作指令。

致谢

感谢书籍《自己动手写CPU》及其作者雷思磊。一并感谢开源精神。



流水线暂停

复杂算术运算,包括乘累加、乘累减、除法等算术运算。这些运算在单个时钟周期不能完成,至少需要 2 个时钟周期。因此在此类指令未执行完毕时,流水线不然能取下一条指令。

MIPS32的暂停机制:

 增加流水线控制模块:

 按照此思路,修改相应模块即可。此处代码和后续的乘加乘减指令一并实现后给出,并验证。

指令说明

madd、maddu、msub、msubu

该 4 条指令均属于 SPECIAL2 类型指令。第 15~6位 为0,可根据低六位判断功能。

指令格式:

 指令用法:

设计

此处给出所有设计模块以及仿真模块源码,方便读者阅读,查看逻辑。

宏定义文件

// |------------------------------ ================================== ------------------------------
// |============================== MIPS32 CPU SYSTEM ALL MACRO DEFINE ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-06
// |Finish Date : 2022-
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》——第4章
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-09
// |Who :Xu Y. B.
// |What:增加如下指令宏定义:
// |	 and、or、xor、nor
// |	 andi、xori
// |	 lui
// |	 sll、sllv、sra、srav.、srl、srlv 
// |	 nop、ssnop、sync、pref
// |	 以及相应的ALU操作功能宏定义
// |Date:2022-12-10
// |Who :Xu Y. B.
// |What:增加如下指令宏定义:
// |	 movz、movn、mfhi、mthi、mfhi、mflo 
// |	 以及相应的ALU操作功能宏定义
// |Date:2022-12-12
// |Who :Xu Y. B.
// |What:增加如下指令宏定义:
// |	 add、addu、sub、subu、slt、sltu、addi、addiu、slti、sltiu、clo、clz、multu、mult、mul
// |	 以及相应的ALU操作功能宏定义
// |Date:2022-12-14
// |Who :Xu Y. B.
// |What:增加如下指令宏定义:
// |	 madd、maddu、msub、msubu
// |	 以及相应的ALU操作功能宏定义

// |--------------------------------------  系统级全局宏定义  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 0字
`define 							DEF_ZERO_WORD						32'd0				// 0字

// | 关于译码
`define 							DEF_ALU_OPR_BUS						7:0					// 译码输出 O_ALU_OPR 总线
`define 							DEF_ALU_SEL_BUS 					2:0					// 译码输出 O_ALU_SEL 总线

// | 逻辑 0 1
`define 							DEF_LOG_TRUE						1'b1				// 逻辑 真
`define 							DEF_LOG_FALSE						1'b0				// 逻辑 假

// | 芯片使能
`define 							DEF_CHIP_EN							1'b1				// 芯片使能
`define 							DEF_CHIP_DIS						1'b0				// 芯片不使能



// |--------------------------------------  指令相关的宏定义  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 指令、功能码
`define 							DEF_ISTC_AND						6'b100100			
`define 							DEF_ISTC_OR							6'b100101			
`define 							DEF_ISTC_XOR						6'b100110			
`define 							DEF_ISTC_NOR						6'b100111			
`define 							DEF_ISTC_ANDI						6'b001100			
`define 							DEF_ISTC_ORI						6'b001101 			
`define 							DEF_ISTC_XORI						6'b001110			
`define 							DEF_ISTC_LUI						6'b001111			

`define 							DEF_ISTC_SLL						6'b000000			
`define 							DEF_ISTC_SLLV						6'b000100			
`define 							DEF_ISTC_SRL						6'b000010			
`define 							DEF_ISTC_SRLV						6'b000110			
`define 							DEF_ISTC_SRA						6'b000011			
`define 							DEF_ISTC_SRAV						6'b000111 			

`define 							DEF_ISTC_SYNC						6'b001111 			
`define 							DEF_ISTC_PREF						6'b110011 			
`define 							DEF_ISTC_SPEC						6'b000000 			// SPECIAL  类指令码
`define 							DEF_ISTC_SPEC2						6'b011100 			// SPECIAL2 类指令码

`define 							DEF_ISTC_MOVZ  						6'b001010
`define 							DEF_ISTC_MOVN  						6'b001011
`define 							DEF_ISTC_MFHI  						6'b010000
`define 							DEF_ISTC_MTHI  						6'b010001
`define 							DEF_ISTC_MFLO  						6'b010010
`define 							DEF_ISTC_MTLO  						6'b010011

`define 							DEF_ISTC_SLT  						6'b101010
`define 							DEF_ISTC_SLTU  						6'b101011
`define 							DEF_ISTC_SLTI  						6'b001010
`define 							DEF_ISTC_SLTIU  					6'b001011   
`define 							DEF_ISTC_ADD  						6'b100000
`define 							DEF_ISTC_ADDU   					6'b100001
`define 							DEF_ISTC_SUB    					6'b100010
`define 							DEF_ISTC_SUBU   					6'b100011
`define 							DEF_ISTC_ADDI   					6'b001000
`define 							DEF_ISTC_ADDIU  					6'b001001
`define 							DEF_ISTC_CLZ    					6'b100000
`define 							DEF_ISTC_CLO    					6'b100001

`define 							DEF_ISTC_MULT   					6'b011000
`define 							DEF_ISTC_MULTU  					6'b011001
`define 							DEF_ISTC_MUL    					6'b000010
`define 							DEF_ISTC_MADD   					6'b000000
`define 							DEF_ISTC_MADDU  					6'b000001
`define 							DEF_ISTC_MSUB   					6'b000100
`define 							DEF_ISTC_MSUBU  					6'b000101
`define 							DEF_ISTC_DIV    					6'b011010
`define 							DEF_ISTC_DIVU   					6'b011011

`define 							DEF_ISTC_NOP						6'b000000			// nop
// | ALU操作码
`define 							DEF_ALU_OR_OPR						8'b00100101			
`define 							DEF_ALU_AND_OPR						8'b00100100			
`define 							DEF_ALU_XOR_OPR						8'b00100110			
`define 							DEF_ALU_NOR_OPR						8'b00100111			

`define 							DEF_ALU_SLL_OPR						8'b01111100			
`define 							DEF_ALU_SRL_OPR						8'b00000010			
`define 							DEF_ALU_SRA_OPR						8'b00000011	

`define 							DEF_ALU_MOVZ_OPR  					8'b00001010
`define 							DEF_ALU_MOVN_OPR  					8'b00001011
`define 							DEF_ALU_MFHI_OPR  					8'b00010000
`define 							DEF_ALU_MTHI_OPR  					8'b00010001
`define 							DEF_ALU_MFLO_OPR  					8'b00010010
`define 							DEF_ALU_MTLO_OPR  					8'b00010011	

`define 							DEF_ALU_SLT_OPR    					8'b00101010
`define 							DEF_ALU_SLTU_OPR   					8'b00101011
`define 							DEF_ALU_SLTI_OPR   					8'b01010111
`define 							DEF_ALU_SLTIU_OPR  					8'b01011000   
`define 							DEF_ALU_ADD_OPR    					8'b00100000
`define 							DEF_ALU_ADDU_OPR   					8'b00100001
`define 							DEF_ALU_SUB_OPR    					8'b00100010
`define 							DEF_ALU_SUBU_OPR   					8'b00100011
`define 							DEF_ALU_ADDI_OPR   					8'b01010101
`define 							DEF_ALU_ADDIU_OPR  					8'b01010110
`define 							DEF_ALU_CLZ_OPR    					8'b10110000
`define 							DEF_ALU_CLO_OPR    					8'b10110001

`define 							DEF_ALU_MULT_OPR   					8'b00011000
`define 							DEF_ALU_MULTU_OPR  					8'b00011001
`define 							DEF_ALU_MUL_OPR    					8'b10101001

`define 							DEF_ALU_MADD_OPR   					8'b10100110
`define 							DEF_ALU_MADDU_OPR   				8'b10101000
`define 							DEF_ALU_MSUB_OPR   					8'b10101010
`define 							DEF_ALU_MSUBU_OPR   				8'b10101011
`define 							DEF_ALU_DIV_OPR   					8'b00011010
`define 							DEF_ALU_DIVU_OPR   					8'b00011011


`define 							DEF_ALU_NOP_OPR						8'd0				

// | ALU 选择
// `define 							DEF_ALU_SEL_LOGIC					3'b001
// `define 							DEF_ALU_SEL_NOP						3'b000				

// | 操作数
`define 							DEF_SRC_OPR_DATA_BUS				31:0
`define 							DEF_IMM_DATA_BUS					15:0


// |--------------------------------------  指令存储器宏定义  --------------------------------------
// |------------------------------------------------------------------------------------------------
`define 							DEF_ISTC_ADDR_BUS					31:0				// 地址线总线
`define 							DEF_ISTC_DATA_BUS 					31:0				// 数据线总线
`define 							DEF_ISTC_CACH_DEPTH					2**17-1				// 缓存深度/地址最大值
`define 							DEF_ISTC_ADDR_WIDTH_ACTUAL			17					// 实际使用的缓存地址线宽度



// |--------------------------------------  通用寄存器宏定义  --------------------------------------
// |------------------------------------------------------------------------------------------------
`define 							DEF_GPR_ADDR_WIDTH					5					// 通用寄存器地址位宽(32个)
`define 							DEF_GPR_DATA_WIDTH					32					// 通用寄存器数据位宽
`define 							DEF_GPR_NUM							32					// 通用寄存器数目
`define 							DEF_GPR_ADDR_NOP					5'd0				// 空操作 GPR 地址

程序计数器模块

// |------------------------------ ================================== ------------------------------
// |============================== 		   程序计数寄存器模块		  ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-06
// |Finish Date : 2022-12-06
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-15
// |Who :Xu Y. B.
// |What:增加流水线指令暂停功能

`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps

module PC_REG_MDL(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
input														  I_CPU_CLK,
input 														  I_CPU_RSTN,
input 														  I_PC_PAUSE,

output 		reg 	[`DEF_ISTC_ADDR_BUS]					  O_PC,
output		reg 											  O_ISTC_ROM_CE
    );

// |--------------------------------------  模块内部逻辑设计  --------------------------------------
// |------------------------------------------------------------------------------------------------
// CE
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_ISTC_ROM_CE <= `DEF_CHIP_DIS;
	end
	else
	begin
		O_ISTC_ROM_CE <= `DEF_CHIP_EN;
	end
end

// PC
always @ (posedge I_CPU_CLK)
begin
	if((~I_CPU_RSTN) || (O_ISTC_ROM_CE == `DEF_CHIP_DIS))
	begin
		O_PC <= 32'd0;
	end
	else if(~I_PC_PAUSE)
	begin
		O_PC <= O_PC + 32'd4;
	end
	else
	begin
		O_PC <= O_PC ;
	end
end

endmodule

译码模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     指令-译码模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-07
// |Finish Date : 2022-12-07
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-08
// |Who :Xu Y. B.
// |What:修复流水线数据相关的问题(第 2、3类问题)
// |	 思路参考《自己动手写CPU》5.2节
// |	 增加模块端口:Line 48 - 54
// |	 增加条件分支:Line 141 - 148 、171 - 178
// |Date:2022-12-09
// |Who :Xu Y. B.
// |What:增加逻辑、移位指令的译码功能
// |Date:2022-12-11
// |Who :Xu Y. B.
// |What:增加移动指令的译码功能
// |Date:2022-12-12
// |Who :Xu Y. B.
// |What:增加简单算术运算指令的译码功能
// |Date:2022-12-14
// |Who :Xu Y. B.
// |What:增加2步算术运算指令的译码功能

`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps


module ID_MDL(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 时钟、复位
input 															I_CPU_CLK,
input 															I_CPU_RSTN,
// | 指令
input 		[`DEF_ISTC_DATA_BUS]								I_ISTC,
// | GPR读写控制
output 	reg														O_GPR_RD_EN_A,
output	reg	[`DEF_GPR_ADDR_WIDTH-1:0]							O_GPR_RD_ADDR_A,
input 		[`DEF_GPR_DATA_WIDTH-1:0]							I_GPR_RD_DATA_A,
output  reg														O_GPR_RD_EN_B,
output  reg	[`DEF_GPR_ADDR_WIDTH-1:0]							O_GPR_RD_ADDR_B,
input 		[`DEF_GPR_DATA_WIDTH-1:0]							I_GPR_RD_DATA_B,
// | 译码输出相关 对接 ALU 运算单元
// output  reg [`DEF_ALU_SEL_BUS]									O_ALU_SEL,
output		[`DEF_ALU_OPR_BUS]									O_ALU_OP_TYPE,
output  reg	[`DEF_SRC_OPR_DATA_BUS]								O_SRC_OPR_DATA_A,
output  reg	[`DEF_SRC_OPR_DATA_BUS]								O_SRC_OPR_DATA_B,

output  reg 													O_DST_GPR_WR_EN,
output  reg [`DEF_GPR_ADDR_WIDTH-1:0]							O_DST_GPR_WR_ADDR,
// | 为解决数据相关问题/读写冲突问题 引入的端口
// 来自执行模块
input 															I_DST_GPR_WR_EN_FROM_EXE_MDL, 
input 		[`DEF_GPR_ADDR_WIDTH-1:0]							I_DST_GPR_WR_ADDR_FROM_EXE_MDL,
input    	[`DEF_GPR_DATA_WIDTH-1:0]							I_DST_GPR_WR_DATA_FROM_EXE_MDL,
// 来自访存模块
input 															I_DST_GPR_WR_EN_FROM_MEM_ACS_MDL, 
input 		[`DEF_GPR_ADDR_WIDTH-1:0]							I_DST_GPR_WR_ADDR_FROM_MEM_ACS_MDL,
input   	[`DEF_GPR_DATA_WIDTH-1:0]							I_DST_GPR_WR_DATA_FROM_MEM_ACS_MDL,
// 流水线暂停
input 		[4:0]												I_PAUSE_ACK,//待优化
output 															O_PAUSE_REQ





    );
// |--------------------------------------  模块内部信号声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 指令分解相关
wire		[5:0]												W_ISTC_TYPE;	// 指令码
wire		[`DEF_GPR_ADDR_WIDTH-1:0]							W_SRC_GPR_ADDR; 
wire 		[`DEF_GPR_ADDR_WIDTH-1:0]							W_DST_GPR_ADDR;
wire		[`DEF_IMM_DATA_BUS]									W_ISTC_IMM_DATA;

wire		[4:0]												W_ISTC_15_11_BIT;
wire		[4:0]												W_ISTC_10_6_BIT;
wire		[5:0]												W_ISTC_5_0_BIT;


// | 32位立即数
reg			[31:0]												R_IMM_DATA_32BIT;

// | 指令有效信号
reg																R_ISTC_VAL;

// 配合流水线暂停功能
wire 		[`DEF_ISTC_DATA_BUS]								W_I_ISTC;

reg 		[`DEF_ALU_OPR_BUS]									R_ALU_OP_TYPE;

reg 		[1:0]												R_PAUSE_REQ;


// |--------------------------------------  模块内部逻辑设计  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 指令分解相关
assign 		W_ISTC_TYPE			=		W_I_ISTC[31:26];// 指令码
assign 		W_SRC_GPR_ADDR  	=       W_I_ISTC[25:21];
assign		W_DST_GPR_ADDR  	=       W_I_ISTC[20:16];
assign 		W_ISTC_IMM_DATA		=		W_I_ISTC[15:0] ;

assign 		W_ISTC_15_11_BIT	=		W_I_ISTC[15:11];
assign		W_ISTC_10_6_BIT		=		W_I_ISTC[10:6];
assign 		W_ISTC_5_0_BIT		=		W_I_ISTC[5:0];

assign      O_PAUSE_REQ			=		R_PAUSE_REQ[0] & (~R_PAUSE_REQ[1]);

// 下面两句故意设置为 锁存器,以满足功能需求
assign 		W_I_ISTC			=		(!I_PAUSE_ACK[1]) ? I_ISTC:W_I_ISTC;
assign 		O_ALU_OP_TYPE 		=		(!I_PAUSE_ACK[1]) ? R_ALU_OP_TYPE:O_ALU_OP_TYPE;


always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		R_PAUSE_REQ <= 2'b00;
	end
	else if(W_ISTC_TYPE == `DEF_ISTC_SPEC2)
	begin
		R_PAUSE_REQ[1] <= R_PAUSE_REQ[0];
		case(W_ISTC_5_0_BIT)
			`DEF_ISTC_MADD,`DEF_ISTC_MADDU,`DEF_ISTC_MSUB,`DEF_ISTC_MSUBU:
			begin
				R_PAUSE_REQ[0] <= 1'b1;
			end
			default:
			begin
				R_PAUSE_REQ[0] <= R_PAUSE_REQ[0];
			end
		endcase
	end
	else
	begin
		R_PAUSE_REQ[0] <= R_PAUSE_REQ[0];
		R_PAUSE_REQ[1] <= R_PAUSE_REQ[0];
	end
end

// | 指令译码 
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_GPR_RD_EN_A	  <= 1'b0;
		O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
		O_GPR_RD_EN_B	  <= 1'b0;
		O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

		R_ALU_OP_TYPE     <= `DEF_ALU_NOP_OPR;
		// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
		O_DST_GPR_WR_EN   <= 1'b0;
		O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;
		
		R_ISTC_VAL		  <= 1'b0;
		R_IMM_DATA_32BIT  <= 32'd0;
	end
	else
	begin
		case(W_ISTC_TYPE)
			`DEF_ISTC_SPEC://SPECIAL 类 指令
			begin
				case(W_ISTC_10_6_BIT)
					5'd0:
					begin
						case(W_ISTC_5_0_BIT)
							`DEF_ISTC_AND:
							begin
								O_GPR_RD_EN_A	  <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B	  <= 1'b1;
								O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_AND_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
								R_ISTC_VAL		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_OR:
							begin
								O_GPR_RD_EN_A	  <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B	  <= 1'b1;
								O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_OR_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
								R_ISTC_VAL		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_XOR:
							begin
								O_GPR_RD_EN_A	  <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B	  <= 1'b1;
								O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_XOR_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
								R_ISTC_VAL		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_NOR:
							begin
								O_GPR_RD_EN_A	  <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B	  <= 1'b1;
								O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_NOR_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
								R_ISTC_VAL		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_SLLV:
							begin
								O_GPR_RD_EN_A	  <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B	  <= 1'b1;
								O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_SLL_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
								R_ISTC_VAL		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_SRLV:
							begin
								O_GPR_RD_EN_A	  <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B	  <= 1'b1;
								O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_SRL_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
								R_ISTC_VAL		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_SRAV:
							begin
								O_GPR_RD_EN_A	  <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B	  <= 1'b1;
								O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_SRA_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
								R_ISTC_VAL		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_SYNC:
							begin
								O_GPR_RD_EN_A	  <= 1'b0;
								O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
								O_GPR_RD_EN_B	  <= 1'b1;
								O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

								R_ALU_OP_TYPE     <= `DEF_ALU_NOP_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b0;
								O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;
		
								R_ISTC_VAL		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_MOVZ:
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_MOVZ_OPR;
								// 写使能此处后置于 执行模块 判断赋值
								// if(I_GPR_RD_DATA_B == `DEF_ZERO_WORD)
								// begin
								// 	O_DST_GPR_WR_EN   <= 1'b1;
								// end
								// else
								// begin
								// 	O_DST_GPR_WR_EN   <= 1'b0;
								// end

								O_DST_GPR_WR_EN   <= 1'b0;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_MOVN:
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_MOVN_OPR;
								// 写使能此处后置于 执行模块 判断赋值
								// if(I_GPR_RD_DATA_B != `DEF_ZERO_WORD)
								// begin
								// 	O_DST_GPR_WR_EN   <= 1'b1;
								// end
								// else
								// begin
								// 	O_DST_GPR_WR_EN   <= 1'b0;
								// end

								O_DST_GPR_WR_EN   <= 1'b0;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_MFHI:
							begin
								O_GPR_RD_EN_A     <= 1'b0;
								O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
								O_GPR_RD_EN_B     <= 1'b0;
								O_GPR_RD_ADDR_B   <= `DEF_GPR_ADDR_NOP;

								R_ALU_OP_TYPE     <= `DEF_ALU_MFHI_OPR;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_MTHI:
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b0;
								O_GPR_RD_ADDR_B   <= `DEF_GPR_ADDR_NOP;

								R_ALU_OP_TYPE     <= `DEF_ALU_MTHI_OPR;
								O_DST_GPR_WR_EN   <= 1'b0;
								O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_MFLO:
							begin
								O_GPR_RD_EN_A     <= 1'b0;
								O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
								O_GPR_RD_EN_B     <= 1'b0;
								O_GPR_RD_ADDR_B   <= `DEF_GPR_ADDR_NOP;

								R_ALU_OP_TYPE     <= `DEF_ALU_MFLO_OPR;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_MTLO:
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b0;
								O_GPR_RD_ADDR_B   <= `DEF_GPR_ADDR_NOP;

								R_ALU_OP_TYPE     <= `DEF_ALU_MTLO_OPR;
								O_DST_GPR_WR_EN   <= 1'b0;
								O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_ADD  :
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_ADD_OPR;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_ADDU :
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_ADDU_OPR;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_SUB  :
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_SUB_OPR;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_SUBU :
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_SUBU_OPR;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_SLT  :
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_SLT_OPR;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_SLTU :
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_SLTU_OPR;
								O_DST_GPR_WR_EN   <= 1'b1;
								O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
							`DEF_ISTC_MULT :
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_MULT_OPR;
								O_DST_GPR_WR_EN   <= 1'b0;
								O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end 
							`DEF_ISTC_MULTU:
							begin
								O_GPR_RD_EN_A     <= 1'b1;
								O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
								O_GPR_RD_EN_B     <= 1'b1;
								O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

								R_ALU_OP_TYPE     <= `DEF_ALU_MULTU_OPR;
								O_DST_GPR_WR_EN   <= 1'b0;
								O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

								R_ISTC_VAL 		  <= 1'b1;
								R_IMM_DATA_32BIT  <= 32'd0;
							end														
							default:
							begin
								O_GPR_RD_EN_A	  <= 1'b0;
								O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
								O_GPR_RD_EN_B	  <= 1'b0;
								O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

								R_ALU_OP_TYPE     <= `DEF_ALU_NOP_OPR;
								// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
								O_DST_GPR_WR_EN   <= 1'b0;
								O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;
		
								R_ISTC_VAL		  <= 1'b0;
								R_IMM_DATA_32BIT  <= 32'd0;
							end
						endcase
					end
					default:
					begin
						O_GPR_RD_EN_A	  <= 1'b0;
						O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
						O_GPR_RD_EN_B	  <= 1'b0;
						O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

						R_ALU_OP_TYPE     <= `DEF_ALU_NOP_OPR;
						// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
						O_DST_GPR_WR_EN   <= 1'b0;
						O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;
		
						R_ISTC_VAL		  <= 1'b0;
						R_IMM_DATA_32BIT  <= 32'd0;
					end
				endcase
			end
			`DEF_ISTC_SPEC2:
			begin
				case(W_ISTC_5_0_BIT)
					`DEF_ISTC_CLZ:
					begin
						O_GPR_RD_EN_A	  <= 1'b1;
						O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
						O_GPR_RD_EN_B	  <= 1'b0;
						O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

						R_ALU_OP_TYPE     <= `DEF_ALU_CLZ_OPR;
						// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
						O_DST_GPR_WR_EN   <= 1'b1;
						O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
						R_ISTC_VAL		  <= 1'b1;
						R_IMM_DATA_32BIT  <= 32'd0;
					end
					`DEF_ISTC_CLO:
					begin
						O_GPR_RD_EN_A	  <= 1'b1;
						O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
						O_GPR_RD_EN_B	  <= 1'b0;
						O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

						R_ALU_OP_TYPE     <= `DEF_ALU_CLO_OPR;
						// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
						O_DST_GPR_WR_EN   <= 1'b1;
						O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
						R_ISTC_VAL		  <= 1'b1;
						R_IMM_DATA_32BIT  <= 32'd0;
					end
					`DEF_ISTC_MUL:
					begin
						O_GPR_RD_EN_A	  <= 1'b1;
						O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
						O_GPR_RD_EN_B	  <= 1'b1;
						O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

						R_ALU_OP_TYPE     <= `DEF_ALU_MUL_OPR;
						// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
						O_DST_GPR_WR_EN   <= 1'b1;
						O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;
		
						R_ISTC_VAL		  <= 1'b1;
						R_IMM_DATA_32BIT  <= 32'd0;
					end
					`DEF_ISTC_MADD:
					begin
						O_GPR_RD_EN_A     <= 1'b1;
						O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
						O_GPR_RD_EN_B     <= 1'b1;
						O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

						R_ALU_OP_TYPE     <= `DEF_ALU_MADD_OPR;
						O_DST_GPR_WR_EN   <= 1'b0;
						O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

						R_ISTC_VAL 		  <= 1'b1;
						R_IMM_DATA_32BIT  <= 32'd0;
					end
					`DEF_ISTC_MADDU:
					begin
						O_GPR_RD_EN_A     <= 1'b1;
						O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
						O_GPR_RD_EN_B     <= 1'b1;
						O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

						R_ALU_OP_TYPE     <= `DEF_ALU_MADDU_OPR;
						O_DST_GPR_WR_EN   <= 1'b0;
						O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

						R_ISTC_VAL 		  <= 1'b1;
						R_IMM_DATA_32BIT  <= 32'd0;						
					end
					`DEF_ISTC_MSUB :
					begin
						O_GPR_RD_EN_A     <= 1'b1;
						O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
						O_GPR_RD_EN_B     <= 1'b1;
						O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

						R_ALU_OP_TYPE     <= `DEF_ALU_MSUB_OPR;
						O_DST_GPR_WR_EN   <= 1'b0;
						O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

						R_ISTC_VAL 		  <= 1'b1;
						R_IMM_DATA_32BIT  <= 32'd0;						
					end
					`DEF_ISTC_MSUBU:
					begin
						O_GPR_RD_EN_A     <= 1'b1;
						O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
						O_GPR_RD_EN_B     <= 1'b1;
						O_GPR_RD_ADDR_B   <= W_DST_GPR_ADDR;

						R_ALU_OP_TYPE     <= `DEF_ALU_MSUBU_OPR;
						O_DST_GPR_WR_EN   <= 1'b0;
						O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

						R_ISTC_VAL 		  <= 1'b1;
						R_IMM_DATA_32BIT  <= 32'd0;						
					end
					default:
					begin
						O_GPR_RD_EN_A	  <= 1'b0;
						O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
						O_GPR_RD_EN_B	  <= 1'b0;
						O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

						R_ALU_OP_TYPE     <= `DEF_ALU_NOP_OPR;
						// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
						O_DST_GPR_WR_EN   <= 1'b0;
						O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;
		
						R_ISTC_VAL		  <= 1'b0;
						R_IMM_DATA_32BIT  <= 32'd0;
					end
				endcase
			end
			`DEF_ISTC_ORI:// ori指令
			begin
				O_GPR_RD_EN_A	  <= 1'b1;
				O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_OR_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b1;
				O_DST_GPR_WR_ADDR <= W_DST_GPR_ADDR;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= {16'd0,W_ISTC_IMM_DATA};
			end
			`DEF_ISTC_ANDI:
			begin
				O_GPR_RD_EN_A	  <= 1'b1;
				O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_AND_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b1;
				O_DST_GPR_WR_ADDR <= W_DST_GPR_ADDR;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= {16'd0,W_ISTC_IMM_DATA};
			end
			`DEF_ISTC_XORI:
			begin
				O_GPR_RD_EN_A	  <= 1'b1;
				O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_XOR_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b1;
				O_DST_GPR_WR_ADDR <= W_DST_GPR_ADDR;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= {16'd0,W_ISTC_IMM_DATA};
			end
			`DEF_ISTC_LUI:
			begin
				O_GPR_RD_EN_A	  <= 1'b1;
				O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_OR_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b1;
				O_DST_GPR_WR_ADDR <= W_DST_GPR_ADDR;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= {W_ISTC_IMM_DATA,16'd0};
			end
			`DEF_ISTC_PREF:
			begin
				O_GPR_RD_EN_A	  <= 1'b0;
				O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_NOP_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b0;
				O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= 32'd0;
			end
			`DEF_ISTC_ADDI :
			begin
				O_GPR_RD_EN_A	  <= 1'b1;
				O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_ADDI_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b1;
				O_DST_GPR_WR_ADDR <= W_DST_GPR_ADDR;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= {{16{W_ISTC_IMM_DATA[15]}},W_ISTC_IMM_DATA};
			end
			`DEF_ISTC_ADDIU:
			begin
				O_GPR_RD_EN_A	  <= 1'b1;
				O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_ADDIU_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b1;
				O_DST_GPR_WR_ADDR <= W_DST_GPR_ADDR;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= {{16{W_ISTC_IMM_DATA[15]}},W_ISTC_IMM_DATA};
			end
			`DEF_ISTC_SLTI :
			begin
				O_GPR_RD_EN_A	  <= 1'b1;
				O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_SLTI_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b1;
				O_DST_GPR_WR_ADDR <= W_DST_GPR_ADDR;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= {{16{W_ISTC_IMM_DATA[15]}},W_ISTC_IMM_DATA};
			end
			`DEF_ISTC_SLTIU:
			begin
				O_GPR_RD_EN_A	  <= 1'b1;
				O_GPR_RD_ADDR_A   <= W_SRC_GPR_ADDR;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_SLTIU_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
				O_DST_GPR_WR_EN   <= 1'b1;
				O_DST_GPR_WR_ADDR <= W_DST_GPR_ADDR;

				R_ISTC_VAL		  <= 1'b1;
				R_IMM_DATA_32BIT  <= {{16{W_ISTC_IMM_DATA[15]}},W_ISTC_IMM_DATA};
			end
			default:
			begin
				O_GPR_RD_EN_A	  <= 1'b0;
				O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
				O_GPR_RD_EN_B	  <= 1'b0;
				O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

				R_ALU_OP_TYPE     <= `DEF_ALU_NOP_OPR;
				// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
				O_DST_GPR_WR_EN   <= 1'b0;
				O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;
		
				R_ISTC_VAL		  <= 1'b0;
				R_IMM_DATA_32BIT  <= 32'd0;
			end
		endcase

		if(W_I_ISTC[31:21] == 11'd0)
		begin
			case(W_ISTC_5_0_BIT)
				`DEF_ISTC_SLL:
				begin
					O_GPR_RD_EN_A	  <= 1'b0;
					O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
					O_GPR_RD_EN_B	  <= 1'b1;
					O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

					R_ALU_OP_TYPE     <= `DEF_ALU_SLL_OPR;
					// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
					O_DST_GPR_WR_EN   <= 1'b1;
					O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

					R_ISTC_VAL		  <= 1'b1;
					R_IMM_DATA_32BIT  <= {27'd0,W_ISTC_10_6_BIT};
				end
				`DEF_ISTC_SRL:
				begin
					O_GPR_RD_EN_A	  <= 1'b0;
					O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
					O_GPR_RD_EN_B	  <= 1'b1;
					O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

					R_ALU_OP_TYPE     <= `DEF_ALU_SRL_OPR;
					// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
					O_DST_GPR_WR_EN   <= 1'b1;
					O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

					R_ISTC_VAL		  <= 1'b1;
					R_IMM_DATA_32BIT  <= {27'd0,W_ISTC_10_6_BIT};
				end
				`DEF_ISTC_SRA:
				begin
					O_GPR_RD_EN_A	  <= 1'b0;
					O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
					O_GPR_RD_EN_B	  <= 1'b1;
					O_GPR_RD_ADDR_B	  <= W_DST_GPR_ADDR;

					R_ALU_OP_TYPE     <= `DEF_ALU_SRA_OPR;
					// O_ALU_SEL         <= `DEF_ALU_SEL_LOGIC;
					O_DST_GPR_WR_EN   <= 1'b1;
					O_DST_GPR_WR_ADDR <= W_ISTC_15_11_BIT;

					R_ISTC_VAL		  <= 1'b1;
					R_IMM_DATA_32BIT  <= {27'd0,W_ISTC_10_6_BIT};
				end
				default:
				begin
					O_GPR_RD_EN_A	  <= 1'b0;
					O_GPR_RD_ADDR_A   <= `DEF_GPR_ADDR_NOP;
					O_GPR_RD_EN_B	  <= 1'b0;
					O_GPR_RD_ADDR_B	  <= `DEF_GPR_ADDR_NOP;

					R_ALU_OP_TYPE     <= `DEF_ALU_NOP_OPR;
					// O_ALU_SEL         <= `DEF_ALU_SEL_NOP;
					O_DST_GPR_WR_EN   <= 1'b0;
					O_DST_GPR_WR_ADDR <= `DEF_GPR_ADDR_NOP;
			
					R_ISTC_VAL		  <= 1'b0;
					R_IMM_DATA_32BIT  <= 32'd0;
				end
			endcase
		end
	end
end

// | 数据输出
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_SRC_OPR_DATA_A <= `DEF_ZERO_WORD;
	end
	else if(I_DST_GPR_WR_EN_FROM_EXE_MDL && O_GPR_RD_EN_A && (O_GPR_RD_ADDR_A == I_DST_GPR_WR_ADDR_FROM_EXE_MDL))
	begin
		O_SRC_OPR_DATA_A <= I_DST_GPR_WR_DATA_FROM_EXE_MDL;
	end
	else if(I_DST_GPR_WR_EN_FROM_MEM_ACS_MDL && O_GPR_RD_EN_A && (O_GPR_RD_ADDR_A == I_DST_GPR_WR_ADDR_FROM_MEM_ACS_MDL))
	begin
		O_SRC_OPR_DATA_A <= I_DST_GPR_WR_DATA_FROM_MEM_ACS_MDL;
	end
	else if(O_GPR_RD_EN_A)
	begin
		O_SRC_OPR_DATA_A <= I_GPR_RD_DATA_A;
	end
	else if(~O_GPR_RD_EN_A)
	begin
		O_SRC_OPR_DATA_A <= R_IMM_DATA_32BIT;
	end
	else
	begin
		O_SRC_OPR_DATA_A <= `DEF_ZERO_WORD;
	end
end


always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_SRC_OPR_DATA_B <= `DEF_ZERO_WORD;
	end
	else if(I_DST_GPR_WR_EN_FROM_EXE_MDL && O_GPR_RD_EN_B && (O_GPR_RD_ADDR_B == I_DST_GPR_WR_ADDR_FROM_EXE_MDL))
	begin
		O_SRC_OPR_DATA_B <= I_DST_GPR_WR_DATA_FROM_EXE_MDL;
	end
	else if(I_DST_GPR_WR_EN_FROM_MEM_ACS_MDL && O_GPR_RD_EN_B && (O_GPR_RD_ADDR_B == I_DST_GPR_WR_ADDR_FROM_MEM_ACS_MDL))
	begin
		O_SRC_OPR_DATA_B <= I_DST_GPR_WR_DATA_FROM_MEM_ACS_MDL;
	end
	else if(O_GPR_RD_EN_B)
	begin
		O_SRC_OPR_DATA_B <= I_GPR_RD_DATA_B;
	end
	else if(~O_GPR_RD_EN_B)
	begin
		O_SRC_OPR_DATA_B <= R_IMM_DATA_32BIT;
	end
	else
	begin
		O_SRC_OPR_DATA_B <= `DEF_ZERO_WORD;
	end
end


endmodule

执行模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     指令-执行模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-07
// |Finish Date : 2022-12-07
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-08
// |Who :Xu Y. B.
// |What:修复流水线数据相关的问题(第 2、3类问题)
// |	 增加模块端口:Line 42 - 44
// |	 两部分输出区别:组合逻辑输出和时序逻辑输出
// |	 代码变动行编号:Line 73、77、84、88、103、111、115、116
// |Date:2022-12-09
// |Who :Xu Y. B.
// |What:增加逻辑、移位运算执行功能
// |Date:2022-12-11
// |Who :Xu Y. B.
// |What:增加移动运算执行功能
// |Date:2022-12-12
// |Who :Xu Y. B.
// |What:增加简单算数运算执行功能
// |Date:2022-12-14
// |Who :Xu Y. B.
// |What:增加2步算数运算执行功能

`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps

module EXE_MDL(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 时钟、复位
input 															I_CPU_CLK,
input 															I_CPU_RSTN,
// | 操作指令
// input		[`DEF_ALU_SEL_BUS]									I_ALU_SEL,		
input 		[`DEF_ALU_OPR_BUS]									I_ALU_OP_TYPE,	
// | 源操作数
input 		[`DEF_SRC_OPR_DATA_BUS]								I_SRC_OPR_DATA_A,
input 		[`DEF_SRC_OPR_DATA_BUS]								I_SRC_OPR_DATA_B,
// | 目的寄存器写
input 															I_DST_GPR_WR_EN,
input 		[`DEF_GPR_ADDR_WIDTH-1:0]							I_DST_GPR_WR_ADDR,

// | HI LO 寄存器
// | HI_LO_REG_MDL 的输出
input		[`DEF_GPR_DATA_WIDTH-1:0]							I_HI,
input		[`DEF_GPR_DATA_WIDTH-1:0]							I_LO,
// | MEM_ACS_MDL 输出
input		[`DEF_GPR_DATA_WIDTH-1:0]							I_HI_FROM_MEM_ACS_MDL,
input		[`DEF_GPR_DATA_WIDTH-1:0]							I_LO_FROM_MEM_ACS_MDL,
input 															I_WR_EN_FROM_MEM_ACS_MDL,
// | HI_LO_REG_MDL 的输入
input		[`DEF_GPR_DATA_WIDTH-1:0]							I_HI_FROM_HI_LO_REG_MDL,
input		[`DEF_GPR_DATA_WIDTH-1:0]							I_LO_FROM_HI_LO_REG_MDL,
input 															I_WR_EN_FROM_HI_LO_REG_MDL,


// | 输出 
output 	reg														O_DST_GPR_WR_EN,   
output 	reg	[`DEF_GPR_ADDR_WIDTH-1:0]							O_DST_GPR_WR_ADDR, 
output  reg [`DEF_GPR_DATA_WIDTH-1:0]							O_DST_GPR_WR_DATA,
// 反馈至 译码模块
output 															O_DST_GPR_WR_EN_2_ID_MDL,   
output 		[`DEF_GPR_ADDR_WIDTH-1:0]							O_DST_GPR_WR_ADDR_2_ID_MDL, 
output  reg [`DEF_GPR_DATA_WIDTH-1:0]							O_DST_GPR_WR_DATA_2_ID_MDL,

// 寄存器输出
output	reg	[`DEF_GPR_DATA_WIDTH-1:0]							O_HI,
output	reg	[`DEF_GPR_DATA_WIDTH-1:0]							O_LO,
output 	reg														O_HILO_WR_EN,

// 流水线暂停
input 		[4:0]												I_PAUSE_ACK,//待优化
output 	reg														O_PAUSE_REQ

    );
// |--------------------------------------  模块内部信号声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | I_ALU_OP_TYPE 打拍
reg 		[`DEF_ALU_OPR_BUS]									R_I_ALU_OP_TYPE;
reg         													R_I_DST_GPR_WR_EN;
reg         [`DEF_GPR_ADDR_WIDTH-1:0]							R_I_DST_GPR_WR_ADDR;

reg 		[`DEF_GPR_DATA_WIDTH-1:0]							R_HI;
reg 		[`DEF_GPR_DATA_WIDTH-1:0]							R_LO; 	
// 组合逻辑输出
reg 		[`DEF_GPR_DATA_WIDTH-1:0]							R_O_HI;
reg 		[`DEF_GPR_DATA_WIDTH-1:0]							R_O_LO;
reg 															R_O_HILO_WR_EN;

wire signed	[`DEF_SRC_OPR_DATA_BUS]								W_I_SRC_OPR_DATA_A_SIGNED;
wire signed	[`DEF_SRC_OPR_DATA_BUS]								W_I_SRC_OPR_DATA_B_SIGNED;	
wire signed [`DEF_SRC_OPR_DATA_BUS]								W_A_ADD_B_SIGNED;
wire signed [`DEF_SRC_OPR_DATA_BUS]								W_A_SUB_B_SIGNED;
wire 															W_OVER_FLOW_FLAG;

// reg         [31:0]												W_MUL_RES_H32;
// 暂存 乘加、乘减 的中间运算结果
reg 		[63:0]												R_MID_RES_MULT;
// 2步运算指令计数器
reg         [1:0]												R_2STEP_ISTC_CNT;//位宽可能存在冗余

// |--------------------------------------  模块内部逻辑设计  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | I_ALU_OP_TYPE 打拍对齐时序
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		R_I_ALU_OP_TYPE <= 0;
	end
	else if(!I_PAUSE_ACK[2])
	begin
		R_I_ALU_OP_TYPE <= I_ALU_OP_TYPE;
	end
	else
	begin
		R_I_ALU_OP_TYPE <= R_I_ALU_OP_TYPE;
	end
end
// | 判断选择最新的 HI LO 
always @ (*)
begin
	if(~I_CPU_RSTN)
	begin
		R_HI = `DEF_ZERO_WORD;
		R_LO = `DEF_ZERO_WORD;
	end
	else if(I_WR_EN_FROM_MEM_ACS_MDL)
	begin
		R_HI = I_HI_FROM_MEM_ACS_MDL;
		R_LO = I_LO_FROM_MEM_ACS_MDL;
	end
	else if(I_WR_EN_FROM_HI_LO_REG_MDL)
	begin
		R_HI = I_HI_FROM_HI_LO_REG_MDL;
		R_LO = I_LO_FROM_HI_LO_REG_MDL;
	end
	else
	begin
		R_HI = I_HI;
		R_LO = I_LO;
	end
end
// | 操作数有符号形式
assign W_I_SRC_OPR_DATA_A_SIGNED = I_SRC_OPR_DATA_A;
assign W_I_SRC_OPR_DATA_B_SIGNED = I_SRC_OPR_DATA_B;
assign W_A_ADD_B_SIGNED          = W_I_SRC_OPR_DATA_A_SIGNED + W_I_SRC_OPR_DATA_B_SIGNED;
assign W_A_SUB_B_SIGNED          = W_I_SRC_OPR_DATA_A_SIGNED - W_I_SRC_OPR_DATA_B_SIGNED;
assign W_OVER_FLOW_FLAG 		 = (!W_I_SRC_OPR_DATA_A_SIGNED[31] && !W_I_SRC_OPR_DATA_B_SIGNED[31] && W_A_ADD_B_SIGNED[31])
								   ||
								   ( W_I_SRC_OPR_DATA_A_SIGNED[31] &&  W_I_SRC_OPR_DATA_B_SIGNED[31] && !W_A_ADD_B_SIGNED[31]);
// | 计算单元
// 组合逻辑
always @ (*)
begin
	if(~I_CPU_RSTN)
	begin
		O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;

		R_O_HILO_WR_EN			   = 1'b0;
		R_O_HI 					   = `DEF_ZERO_WORD;
		R_O_LO 					   = `DEF_ZERO_WORD;
	end
	else
	begin
		case(R_I_ALU_OP_TYPE)
			`DEF_ALU_OR_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_A | I_SRC_OPR_DATA_B;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_AND_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_A & I_SRC_OPR_DATA_B;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_XOR_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_A ^ I_SRC_OPR_DATA_B;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_NOR_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = ~(I_SRC_OPR_DATA_A | I_SRC_OPR_DATA_B);

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_SLL_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_B << I_SRC_OPR_DATA_A;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_SRL_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_B >> I_SRC_OPR_DATA_A;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_SRA_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = ({32{I_SRC_OPR_DATA_B[31]}} << (6'd32 - I_SRC_OPR_DATA_A[5:0])) | (I_SRC_OPR_DATA_B >> I_SRC_OPR_DATA_A);

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_MOVZ_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_A;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_MOVN_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_A;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_MFHI_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = R_HI;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_MTHI_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;

				R_O_HILO_WR_EN			   = 1'b1;
				R_O_HI 					   = I_SRC_OPR_DATA_A;
				R_O_LO 					   = R_LO;
			end
			`DEF_ALU_MFLO_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = R_LO;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
			`DEF_ALU_MTLO_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;

				R_O_HILO_WR_EN			   = 1'b1;
				R_O_HI 					   = R_HI;
				R_O_LO 					   = I_SRC_OPR_DATA_A;
			end
			`DEF_ALU_SLT_OPR  :
			begin
				if(W_I_SRC_OPR_DATA_A_SIGNED < W_I_SRC_OPR_DATA_B_SIGNED)
				begin
					O_DST_GPR_WR_DATA_2_ID_MDL = 32'd1;
				end
				else
				begin
					O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
				end

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;			
			end
			`DEF_ALU_SLTU_OPR :
			begin
				if(I_SRC_OPR_DATA_A < I_SRC_OPR_DATA_B)
				begin
					O_DST_GPR_WR_DATA_2_ID_MDL = 32'd1;
				end
				else
				begin
					O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
				end

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;				
			end
			`DEF_ALU_SLTI_OPR :
			begin
				if(W_I_SRC_OPR_DATA_A_SIGNED < W_I_SRC_OPR_DATA_B_SIGNED)
				begin
					O_DST_GPR_WR_DATA_2_ID_MDL = 32'd1;
				end
				else
				begin
					O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
				end

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;					
			end
			`DEF_ALU_SLTIU_OPR:
			begin
				if(I_SRC_OPR_DATA_A < I_SRC_OPR_DATA_B)
				begin
					O_DST_GPR_WR_DATA_2_ID_MDL = 32'd1;
				end
				else
				begin
					O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
				end

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;				
			end
			`DEF_ALU_ADD_OPR  :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = W_A_ADD_B_SIGNED;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;				
			end
			`DEF_ALU_ADDU_OPR :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = W_A_ADD_B_SIGNED;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;				
			end
			`DEF_ALU_SUB_OPR  :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = W_A_SUB_B_SIGNED;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;					
			end
			`DEF_ALU_SUBU_OPR :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = W_A_SUB_B_SIGNED;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;				
			end
			`DEF_ALU_ADDI_OPR :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = W_A_ADD_B_SIGNED;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;					
			end
			`DEF_ALU_ADDIU_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = W_A_ADD_B_SIGNED;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;					
			end
			`DEF_ALU_CLZ_OPR  :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_A[31] ? 0  : I_SRC_OPR_DATA_A[30] ? 1  : I_SRC_OPR_DATA_A[29] ? 2  : I_SRC_OPR_DATA_A[28] ? 3  :
											 I_SRC_OPR_DATA_A[27] ? 4  : I_SRC_OPR_DATA_A[26] ? 5  : I_SRC_OPR_DATA_A[25] ? 6  : I_SRC_OPR_DATA_A[24] ? 7  :
											 I_SRC_OPR_DATA_A[23] ? 8  : I_SRC_OPR_DATA_A[22] ? 9  : I_SRC_OPR_DATA_A[21] ? 10 : I_SRC_OPR_DATA_A[20] ? 11 :
											 I_SRC_OPR_DATA_A[19] ? 12 : I_SRC_OPR_DATA_A[18] ? 13 : I_SRC_OPR_DATA_A[17] ? 14 : I_SRC_OPR_DATA_A[16] ? 15 :
											 I_SRC_OPR_DATA_A[15] ? 16 : I_SRC_OPR_DATA_A[14] ? 17 : I_SRC_OPR_DATA_A[13] ? 18 : I_SRC_OPR_DATA_A[12] ? 19 :
											 I_SRC_OPR_DATA_A[11] ? 20 : I_SRC_OPR_DATA_A[10] ? 21 : I_SRC_OPR_DATA_A[9]  ? 22 : I_SRC_OPR_DATA_A[8]  ? 23 :
											 I_SRC_OPR_DATA_A[7]  ? 24 : I_SRC_OPR_DATA_A[6]  ? 25 : I_SRC_OPR_DATA_A[5]  ? 26 : I_SRC_OPR_DATA_A[4]  ? 27 :
											 I_SRC_OPR_DATA_A[3]  ? 28 : I_SRC_OPR_DATA_A[2]  ? 29 : I_SRC_OPR_DATA_A[1]  ? 30 : I_SRC_OPR_DATA_A[0]  ? 31 : 32;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;				
			end
			`DEF_ALU_CLO_OPR  :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = !I_SRC_OPR_DATA_A[31] ? 0  : !I_SRC_OPR_DATA_A[30] ? 1  : !I_SRC_OPR_DATA_A[29] ? 2  : !I_SRC_OPR_DATA_A[28] ? 3  :
											 !I_SRC_OPR_DATA_A[27] ? 4  : !I_SRC_OPR_DATA_A[26] ? 5  : !I_SRC_OPR_DATA_A[25] ? 6  : !I_SRC_OPR_DATA_A[24] ? 7  :
											 !I_SRC_OPR_DATA_A[23] ? 8  : !I_SRC_OPR_DATA_A[22] ? 9  : !I_SRC_OPR_DATA_A[21] ? 10 : !I_SRC_OPR_DATA_A[20] ? 11 :
											 !I_SRC_OPR_DATA_A[19] ? 12 : !I_SRC_OPR_DATA_A[18] ? 13 : !I_SRC_OPR_DATA_A[17] ? 14 : !I_SRC_OPR_DATA_A[16] ? 15 :
											 !I_SRC_OPR_DATA_A[15] ? 16 : !I_SRC_OPR_DATA_A[14] ? 17 : !I_SRC_OPR_DATA_A[13] ? 18 : !I_SRC_OPR_DATA_A[12] ? 19 :
											 !I_SRC_OPR_DATA_A[11] ? 20 : !I_SRC_OPR_DATA_A[10] ? 21 : !I_SRC_OPR_DATA_A[9]  ? 22 : !I_SRC_OPR_DATA_A[8]  ? 23 :
											 !I_SRC_OPR_DATA_A[7]  ? 24 : !I_SRC_OPR_DATA_A[6]  ? 25 : !I_SRC_OPR_DATA_A[5]  ? 26 : !I_SRC_OPR_DATA_A[4]  ? 27 :
											 !I_SRC_OPR_DATA_A[3]  ? 28 : !I_SRC_OPR_DATA_A[2]  ? 29 : !I_SRC_OPR_DATA_A[1]  ? 30 : !I_SRC_OPR_DATA_A[0]  ? 31 : 32;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;				
			end
			`DEF_ALU_MULT_OPR :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;

				R_O_HILO_WR_EN			   = 1'b1;
				{R_O_HI,R_O_LO}			   = W_I_SRC_OPR_DATA_A_SIGNED * W_I_SRC_OPR_DATA_B_SIGNED;				
			end
			`DEF_ALU_MULTU_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;

				R_O_HILO_WR_EN			   = 1'b1;
				{R_O_HI,R_O_LO}			   = I_SRC_OPR_DATA_A * I_SRC_OPR_DATA_B;				
			end
			`DEF_ALU_MUL_OPR  :
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = W_I_SRC_OPR_DATA_A_SIGNED * W_I_SRC_OPR_DATA_B_SIGNED;	

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;			
			end		
			`DEF_ALU_MADD_OPR ,`DEF_ALU_MADDU_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
				if(R_2STEP_ISTC_CNT == 1)
				begin
					R_O_HILO_WR_EN			   = 1'b1;
					{R_O_HI,R_O_LO}			   = {R_HI[31],R_HI,R_LO} + {R_MID_RES_MULT[63],R_MID_RES_MULT};	
				end
				else
				begin
					R_O_HILO_WR_EN			   = 1'b0;
					R_O_HI 					   = `DEF_ZERO_WORD;
					R_O_LO 					   = `DEF_ZERO_WORD;					
				end
			end
			`DEF_ALU_MSUB_OPR ,`DEF_ALU_MSUBU_OPR:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
				if(R_2STEP_ISTC_CNT == 1)
				begin
					R_O_HILO_WR_EN			   = 1'b1;
					{R_O_HI,R_O_LO}			   = {R_HI[31],R_HI,R_LO} - {R_MID_RES_MULT[63],R_MID_RES_MULT};
				end
				else
				begin
					R_O_HILO_WR_EN			   = 1'b0;
					R_O_HI 					   = `DEF_ZERO_WORD;
					R_O_LO 					   = `DEF_ZERO_WORD;					
				end
			end
			default:
			begin
				O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;

				R_O_HILO_WR_EN			   = 1'b0;
				R_O_HI 					   = `DEF_ZERO_WORD;
				R_O_LO 					   = `DEF_ZERO_WORD;
			end
		endcase
	end
end

// HI LO 寄存输出
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_HILO_WR_EN <= 1'b0;
		O_HI 		 <= 32'd0;
		O_LO 		 <= 32'd0;
	end
	else
	begin
		if(!I_PAUSE_ACK[2])
		begin
			O_HILO_WR_EN <= R_O_HILO_WR_EN;
			O_HI 		 <= R_O_HI 		;
			O_LO 		 <= R_O_LO 		;	
		end	
		else
		begin
			O_HILO_WR_EN <= 1'b0;
			O_HI 		 <= 32'd0;
			O_LO 		 <= 32'd0;			
		end
	end
end

// | 写操作打拍
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_DST_GPR_WR_EN <= 1'b0;
		O_DST_GPR_WR_ADDR <= 5'd0;
		R_I_DST_GPR_WR_EN <= 1'b0;
		R_I_DST_GPR_WR_ADDR <= 5'd0;
		O_DST_GPR_WR_DATA <= `DEF_ZERO_WORD;
	end
	else
	begin
		if(!I_PAUSE_ACK[2])
		begin
			R_I_DST_GPR_WR_EN <= I_DST_GPR_WR_EN;
			R_I_DST_GPR_WR_ADDR <= I_DST_GPR_WR_ADDR;

			if(R_I_ALU_OP_TYPE == `DEF_ALU_MOVZ_OPR) 
			begin
				if(I_SRC_OPR_DATA_B == `DEF_ZERO_WORD)
				begin
					O_DST_GPR_WR_EN   <= 1'b1;
				end
				else
				begin
					O_DST_GPR_WR_EN   <= 1'b0;
				end
			end
			else if(R_I_ALU_OP_TYPE == `DEF_ALU_MOVN_OPR)
			begin
				if(I_SRC_OPR_DATA_B == `DEF_ZERO_WORD)
				begin
					O_DST_GPR_WR_EN   <= 1'b0;
				end
				else
				begin
					O_DST_GPR_WR_EN   <= 1'b1;
				end
			end
			else if((R_I_ALU_OP_TYPE == `DEF_ALU_ADD_OPR || R_I_ALU_OP_TYPE == 	`DEF_ALU_SUB_OPR || R_I_ALU_OP_TYPE == `DEF_ALU_ADDI_OPR) && W_OVER_FLOW_FLAG)
			begin
				O_DST_GPR_WR_EN <= 1'b0;
			end
			else
			begin
				O_DST_GPR_WR_EN <= R_I_DST_GPR_WR_EN;
			end
			O_DST_GPR_WR_ADDR <= R_I_DST_GPR_WR_ADDR;
			O_DST_GPR_WR_DATA <= O_DST_GPR_WR_DATA_2_ID_MDL;
		end
		else
		begin
			O_DST_GPR_WR_EN <= 1'b0;
			O_DST_GPR_WR_ADDR <= 5'd0;
			R_I_DST_GPR_WR_EN <= 1'b0;
			R_I_DST_GPR_WR_ADDR <= 5'd0;
			O_DST_GPR_WR_DATA <= `DEF_ZERO_WORD;			
		end
	end
end

assign O_DST_GPR_WR_EN_2_ID_MDL     =    R_I_DST_GPR_WR_EN  ;   
assign O_DST_GPR_WR_ADDR_2_ID_MDL   =    R_I_DST_GPR_WR_ADDR; 


always @ (*)
begin
	if(~I_CPU_RSTN)
	begin
		O_PAUSE_REQ = 1'b0;
	end
	else
	begin
		case(R_I_ALU_OP_TYPE)
			`DEF_ALU_MADD_OPR,`DEF_ALU_MADDU_OPR,`DEF_ALU_MSUB_OPR,`DEF_ALU_MSUBU_OPR,`DEF_ALU_DIV_OPR,`DEF_ALU_DIVU_OPR:
			begin
				if(R_2STEP_ISTC_CNT == 0)
				begin
					O_PAUSE_REQ = 1'b1;
				end
				else if(R_2STEP_ISTC_CNT == 1)
				begin
					O_PAUSE_REQ = 1'b0;
				end
				else 
				begin
					O_PAUSE_REQ = 1'b1;
				end
			end
			default:
			begin
				O_PAUSE_REQ = 1'b0;
			end
		endcase
	end
end

always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		R_2STEP_ISTC_CNT <= 2'd0;
	end
	else
	begin
		case(R_I_ALU_OP_TYPE)
			`DEF_ALU_MADD_OPR,`DEF_ALU_MADDU_OPR,`DEF_ALU_MSUB_OPR,`DEF_ALU_MSUBU_OPR,`DEF_ALU_DIV_OPR,`DEF_ALU_DIVU_OPR:
			begin
				if(R_2STEP_ISTC_CNT == 1)
				begin
					R_2STEP_ISTC_CNT <= 2'd0;
				end
				else
				begin
					R_2STEP_ISTC_CNT <= R_2STEP_ISTC_CNT + 1;
				end
			end
			default:
			begin
				R_2STEP_ISTC_CNT <= 2'd0;
			end
		endcase
	end
end

always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		R_MID_RES_MULT <= 64'd0;
	end
	else
	begin
		case(R_I_ALU_OP_TYPE)
			`DEF_ALU_MADD_OPR,`DEF_ALU_MADDU_OPR,`DEF_ALU_MSUB_OPR,`DEF_ALU_MSUBU_OPR,`DEF_ALU_DIV_OPR,`DEF_ALU_DIVU_OPR:
			begin
				if(R_2STEP_ISTC_CNT == 0)
				begin
					if(R_I_ALU_OP_TYPE == `DEF_ALU_MADD_OPR || R_I_ALU_OP_TYPE == `DEF_ALU_MSUB_OPR)
					begin
						R_MID_RES_MULT <= W_I_SRC_OPR_DATA_A_SIGNED * W_I_SRC_OPR_DATA_B_SIGNED;
					end
					else if(R_I_ALU_OP_TYPE == `DEF_ALU_MADDU_OPR || R_I_ALU_OP_TYPE == `DEF_ALU_MSUBU_OPR)
					begin
						R_MID_RES_MULT <= I_SRC_OPR_DATA_A * I_SRC_OPR_DATA_B;
					end
					else
					begin
						R_MID_RES_MULT <= R_MID_RES_MULT;
					end
				end
				else
				begin
					R_MID_RES_MULT <= R_MID_RES_MULT;
				end
			end
			default:
			begin
				R_MID_RES_MULT <= 64'd0;
			end
		endcase
	end
end

endmodule

访存模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     -执行模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-07
// |Finish Date : 2022-12-07
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-14
// |Who :Xu Y. B.
// |What:增加流水线指令暂停模块


`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps



module MEM_ACS_MDL(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 时钟、复位
input 															I_CPU_CLK,
input 															I_CPU_RSTN,
// | 前接指令执行模块输出
input 															I_DST_GPR_WR_EN,  
input 		[`DEF_GPR_ADDR_WIDTH-1:0]							I_DST_GPR_WR_ADDR,
input 		[`DEF_GPR_DATA_WIDTH-1:0]							I_DST_GPR_WR_DATA,

// | 后接写回模块
output reg  													O_DST_GPR_WR_EN,  
output reg  [`DEF_GPR_ADDR_WIDTH-1:0]							O_DST_GPR_WR_ADDR,
output reg  [`DEF_GPR_DATA_WIDTH-1:0]							O_DST_GPR_WR_DATA,

input		[`DEF_GPR_DATA_WIDTH-1:0]							I_HI,
input		[`DEF_GPR_DATA_WIDTH-1:0]							I_LO,
input 															I_HILO_WR_EN,

output	reg	[`DEF_GPR_DATA_WIDTH-1:0]							O_HI,
output	reg	[`DEF_GPR_DATA_WIDTH-1:0]							O_LO,
output 	reg														O_HILO_WR_EN,

// 流水线暂停
input 		[4:0]												I_PAUSE_ACK//待优化
// output 	reg														O_PAUSE_REQ

    );
// |--------------------------------------  模块内部逻辑设计  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 目的寄存器写操作传递/打拍
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_DST_GPR_WR_EN   <= 1'b0;  
		O_DST_GPR_WR_ADDR <= 5'd0;
		O_DST_GPR_WR_DATA <= 32'd0;		

		O_HI 			  <= 32'd0;
		O_LO 			  <= 32'd0;
		O_HILO_WR_EN 	  <= 1'b0;		
	end
	else
	begin
		if(!I_PAUSE_ACK[3])
		begin
			O_DST_GPR_WR_EN   <= I_DST_GPR_WR_EN  ;  
			O_DST_GPR_WR_ADDR <= I_DST_GPR_WR_ADDR;
			O_DST_GPR_WR_DATA <= I_DST_GPR_WR_DATA;		

			O_HI              <= I_HI ;
			O_LO              <= I_LO ;
			O_HILO_WR_EN      <= I_HILO_WR_EN;
		end
		else
		begin
			O_DST_GPR_WR_EN   <= 1'b0;  
			O_DST_GPR_WR_ADDR <= 5'd0;
			O_DST_GPR_WR_DATA <= 32'd0;		

			O_HI 			  <= 32'd0;
			O_LO 			  <= 32'd0;
			O_HILO_WR_EN 	  <= 1'b0;				
		end
	end
end


endmodule

HI LO 寄存器模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     指令-译码模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-10
// |Finish Date : 2022-12-10
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:
// |Who :
// |What:

`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps

module HI_LO_REG_MDL(
// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 时钟、复位
input 															I_CPU_CLK,
input 															I_CPU_RSTN,

input 															I_HILO_WR_EN,
input 			[`DEF_GPR_DATA_WIDTH-1:0]						I_HI,
input			[`DEF_GPR_DATA_WIDTH-1:0]						I_LO,

output	reg		[`DEF_GPR_DATA_WIDTH-1:0]						O_HI,
output	reg		[`DEF_GPR_DATA_WIDTH-1:0]						O_LO

    );

// |--------------------------------------  模块内部逻辑设计  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 寄存
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_HI <= `DEF_ZERO_WORD;
		O_LO <= `DEF_ZERO_WORD;
	end
	else if(I_HILO_WR_EN)
	begin
		O_HI <= I_HI;
		O_LO <= I_LO;
	end
	else
	begin
		O_HI <= O_HI;
		O_LO <= O_LO;		
	end
end
endmodule

通用寄存器模块

// |------------------------------ ================================== ------------------------------
// |============================== 		   取指-译码接口模块	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-06
// |Finish Date : 2022-12-06
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-
// |Who :Xu Y. B.
// |What:

`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps

module GPR_WR_RD_MDL(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 时钟、复位
input 															I_CPU_CLK,
input 															I_CPU_RSTN,
// | 写
input 															I_GPR_WR_EN,
input 		[`DEF_GPR_ADDR_WIDTH-1:0]							I_GPR_WR_ADDR,
input 		[`DEF_GPR_DATA_WIDTH-1:0]							I_GPR_WR_DATA,
// |读
input 															I_GPR_RD_EN_A,
input 		[`DEF_GPR_ADDR_WIDTH-1:0]							I_GPR_RD_ADDR_A,
output	reg	[`DEF_GPR_DATA_WIDTH-1:0]							O_GPR_RD_DATA_A,
input 															I_GPR_RD_EN_B,
input 		[`DEF_GPR_ADDR_WIDTH-1:0]							I_GPR_RD_ADDR_B,
output	reg	[`DEF_GPR_DATA_WIDTH-1:0]							O_GPR_RD_DATA_B

    );
// |--------------------------------------  GPR-寄存器组定义  --------------------------------------
// |------------------------------------------------------------------------------------------------
reg 		[`DEF_GPR_DATA_WIDTH-1:0]							R_GPR [`DEF_GPR_NUM-1:0];

// |--------------------------------------  GPR-寄存器初始化  --------------------------------------
// |------------------------------------------------------------------------------------------------
initial $readmemh("D:/VIVADO_WORK_SPACE/CPU_MIPS32/DATA_FILE/GPR_INIT.txt",R_GPR);

// |--------------------------------------  GPR-寄存器写操作  --------------------------------------
// |------------------------------------------------------------------------------------------------
always @ (posedge I_CPU_CLK)
begin
	if(I_CPU_RSTN)
	begin
		if(I_GPR_WR_EN && I_GPR_WR_ADDR != `DEF_GPR_ADDR_WIDTH'd0)
		begin
			R_GPR[I_GPR_WR_ADDR] <= I_GPR_WR_DATA;
		end
	end
end

// |--------------------------------------    PORT A 读操作   --------------------------------------
// |------------------------------------------------------------------------------------------------
always @ (*)
begin
	if(~I_CPU_RSTN)
	begin
		O_GPR_RD_DATA_A = `DEF_ZERO_WORD;
	end
	else if(I_GPR_WR_EN && I_GPR_RD_EN_A && (I_GPR_RD_ADDR_A == I_GPR_WR_ADDR))
	begin
		O_GPR_RD_DATA_A = I_GPR_WR_DATA;
	end
	else if(I_GPR_RD_EN_A)
	begin
		O_GPR_RD_DATA_A = R_GPR[I_GPR_RD_ADDR_A];
	end
	else
	begin
		O_GPR_RD_DATA_A = `DEF_ZERO_WORD;
	end
end


// |--------------------------------------    PORT B 读操作   --------------------------------------
// |------------------------------------------------------------------------------------------------
always @ (*)
begin
	if(~I_CPU_RSTN)
	begin
		O_GPR_RD_DATA_B = `DEF_ZERO_WORD;
	end
	else if(I_GPR_WR_EN && I_GPR_RD_EN_B && (I_GPR_RD_ADDR_B == I_GPR_WR_ADDR))
	begin
		O_GPR_RD_DATA_B = I_GPR_WR_DATA;
	end
	else if(I_GPR_RD_EN_B)
	begin
		O_GPR_RD_DATA_B = R_GPR[I_GPR_RD_ADDR_B];
	end
	else
	begin
		O_GPR_RD_DATA_B = `DEF_ZERO_WORD;
	end
end


endmodule

流水线控制模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     指令-执行模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-12
// |Finish Date : 2022-12-12
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-12
// |Who :Xu Y. B.
// |What:

module PIPE_LINE_CTRL_MDL(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 时钟、复位
input 															I_CPU_CLK,
input 															I_CPU_RSTN,

input 															I_PAUSE_REQ_FROM_ID_MDL,
input 															I_PAUSE_REQ_FROM_EXE_MDL,

output 	reg		[4:0]											O_PAUSE_ACK
// O_PAUSE_ACK[0] ——> PC_REG_MDL
// O_PAUSE_ACK[1] ——> ID_MDL
// O_PAUSE_ACK[2] ——> EXE_MDL
// O_PAUSE_ACK[3] ——> MEM_ACS_MDL
// O_PAUSE_ACK[4] ——> HI_LO_REG_MDL

    );
// always @ (posedge I_CPU_CLK)
always @ (*)
begin
	if(~I_CPU_RSTN)
	begin
		O_PAUSE_ACK <= 5'd0;
	end
	else if(I_PAUSE_REQ_FROM_EXE_MDL)
	begin
		O_PAUSE_ACK <= 5'b0_0_1_1_1;
	end
	else if(I_PAUSE_REQ_FROM_ID_MDL)
	begin
		O_PAUSE_ACK <= 5'b0_0_0_1_1;
	end
	else
	begin
		O_PAUSE_ACK <= 5'd0;
	end
end
endmodule

程序ROM

// |------------------------------ ================================== ------------------------------
// |============================== 		   程序计数寄存器模块		  ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-08
// |Finish Date : 2022-12-08
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-
// |Who :Xu Y. B.
// |What:

`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps



module ROM_ISTC_MDL(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
input														  I_CPU_CLK,
input 														  I_CPU_RSTN,

input														  I_RD_EN,
input 			[`DEF_ISTC_ADDR_BUS]						  I_RD_ADDR,

output	reg		[`DEF_ISTC_DATA_BUS]						  O_ISTC
    );

// |--------------------------------------  模块内部信号声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | ROM空间开辟
reg				[`DEF_ISTC_DATA_BUS]						  R_ROM_DATA [`DEF_ISTC_CACH_DEPTH:0];
// |--------------------------------------  模块内部逻辑设计  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | ROM初始化
initial $readmemh("D:/Ubuntu_Win_Share/My_MIPS32/TEST/ISTC_ROM.data",R_ROM_DATA);
// | 数据读取
always @ (posedge I_CPU_CLK)
begin
	if(~I_CPU_RSTN)
	begin
		O_ISTC <= `DEF_ZERO_WORD;
	end
	else
	begin
		if(I_RD_EN)
		begin
			O_ISTC <= R_ROM_DATA[I_RD_ADDR[`DEF_ISTC_ADDR_WIDTH_ACTUAL+1:2]];
		end
		else
		begin
			O_ISTC <= `DEF_ZERO_WORD;
		end
	end
end
endmodule

MIPS32顶层

// |------------------------------ ================================== ------------------------------
// |============================== 		     指令-执行模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-07
// |Finish Date : 2022-12-07
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-08
// |Who :Xu Y. B.
// |What:修复流水线数据相关的问题(第 2、3类问题)
// |	 顶层文件配合改动


`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps

module TOP_MIPS32(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 时钟、复位
input 															I_CPU_CLK,
input 															I_CPU_RSTN,
// | 指令取
input			[`DEF_ISTC_DATA_BUS]							I_ISTC_FROM_ROM,
output			[`DEF_ISTC_ADDR_BUS]							O_ISTC_ADDR_2_ROM,
// | 指令存储器使能
output															O_ISTC_ROM_CE
    );

// |--------------------------------------  模块内部信号声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | PC_REG_MDL 输出
wire			[`DEF_ISTC_ADDR_BUS]							W_PC;
// | IF_ID_MDL 输出
wire 			[`DEF_ISTC_ADDR_BUS] 							W_ID_ADDR;
wire 			[`DEF_ISTC_DATA_BUS] 							W_ID_DATA;
// ID_MDL 端口信号(GPR相关)
wire															W_GPR_RD_EN_A;
(*DONT_TOUCH = "TRUE"*)
wire			[`DEF_GPR_ADDR_WIDTH-1:0]						W_GPR_RD_ADDR_A;
wire			[`DEF_GPR_DATA_WIDTH-1:0]						W_GPR_RD_DATA_A;
wire															W_GPR_RD_EN_B;
(*DONT_TOUCH = "TRUE"*)
wire			[`DEF_GPR_ADDR_WIDTH-1:0]						W_GPR_RD_ADDR_B;
wire 			[`DEF_GPR_DATA_WIDTH-1:0]						W_GPR_RD_DATA_B;
// ID_MDL 端口信号(EXE 相关)
wire			[`DEF_ALU_OPR_BUS]								W_ALU_OP_TYPE;
wire			[`DEF_SRC_OPR_DATA_BUS]							W_SRC_OPR_DATA_A;
wire			[`DEF_SRC_OPR_DATA_BUS]							W_SRC_OPR_DATA_B;
// GPR_WR_RD_MDL 写操作端口(EXE 相关)
wire															W_DST_GPR_WR_EN_EXE_MDL_IN;
wire			[`DEF_GPR_ADDR_WIDTH-1:0]						W_DST_GPR_WR_ADDR_EXE_MDL_IN;
// GPR_WR_RD_MDL 写操作端口(MEM 相关)
wire															W_DST_GPR_WR_EN_MEM_MDL_IN;
wire			[`DEF_GPR_ADDR_WIDTH-1:0]						W_DST_GPR_WR_ADDR_MEM_MDL_IN;
wire			[`DEF_GPR_DATA_WIDTH-1:0]						W_DST_GPR_WR_DATA_MEM_MDL_IN;
// GPR_WR_RD_MDL 写操作端口(GPR 相关)
wire															W_DST_GPR_WR_EN_GPR_MDL_IN;
wire			[`DEF_GPR_ADDR_WIDTH-1:0]						W_DST_GPR_WR_ADDR_GPR_MDL_IN;
wire			[`DEF_GPR_DATA_WIDTH-1:0]						W_DST_GPR_WR_DATA_GPR_MDL_IN;
// | 为解决数据相关问题/读写冲突问题 引入的端口
// 来自执行模块
wire															W_DST_GPR_WR_EN_GPR_MDL_IN_FROM_EXE_MDL  ;
wire			[`DEF_GPR_ADDR_WIDTH-1:0]						W_DST_GPR_WR_ADDR_GPR_MDL_IN_FROM_EXE_MDL;
wire			[`DEF_GPR_DATA_WIDTH-1:0]						W_DST_GPR_WR_DATA_GPR_MDL_IN_FROM_EXE_MDL;
// | HI_LO_REG_MDL 端口
wire 															W_HILO_WR_EN;
wire 			[`DEF_GPR_DATA_WIDTH-1:0]						W_HI;
wire			[`DEF_GPR_DATA_WIDTH-1:0]						W_LO;
wire 			[`DEF_GPR_DATA_WIDTH-1:0]						W_O_HI;
wire			[`DEF_GPR_DATA_WIDTH-1:0]						W_O_LO;
wire 															W_O_EXE_HILO_WR_EN;
wire 			[`DEF_GPR_DATA_WIDTH-1:0]						W_O_EXE_HI;
wire			[`DEF_GPR_DATA_WIDTH-1:0]						W_O_EXE_LO;
// | PIPE_LINE_CTRL_MDL 端口
wire															W_PAUSE_REQ_FROM_ID_MDL;
wire															W_PAUSE_REQ_FROM_EXE_MDL;
wire			[4:0]											W_PAUSE_ACK;
// |--------------------------------------  模块内部逻辑设计  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 输出
assign 			O_ISTC_ADDR_2_ROM		=		W_PC;

// |--------------------------------------      子模块例化    --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 程序计数器模块
	PC_REG_MDL INST_PC_REG_MDL
		(
			.I_CPU_CLK     (I_CPU_CLK),
			.I_CPU_RSTN    (I_CPU_RSTN),
			.I_PC_PAUSE    (W_PAUSE_ACK[0]),
			.O_PC          (W_PC),
			.O_ISTC_ROM_CE (O_ISTC_ROM_CE)
		);
// | 译码模块例化
	ID_MDL INST_ID_MDL
		(
			.I_CPU_CLK         (I_CPU_CLK),
			.I_CPU_RSTN        (I_CPU_RSTN),
			.I_ISTC            (I_ISTC_FROM_ROM),

			.O_GPR_RD_EN_A     (W_GPR_RD_EN_A),
			.O_GPR_RD_ADDR_A   (W_GPR_RD_ADDR_A),
			.I_GPR_RD_DATA_A   (W_GPR_RD_DATA_A),
			.O_GPR_RD_EN_B     (W_GPR_RD_EN_B),
			.O_GPR_RD_ADDR_B   (W_GPR_RD_ADDR_B),
			.I_GPR_RD_DATA_B   (W_GPR_RD_DATA_B),

			.O_ALU_OP_TYPE     (W_ALU_OP_TYPE),
			.O_SRC_OPR_DATA_A  (W_SRC_OPR_DATA_A),
			.O_SRC_OPR_DATA_B  (W_SRC_OPR_DATA_B),

			.O_DST_GPR_WR_EN   (W_DST_GPR_WR_EN_EXE_MDL_IN),
			.O_DST_GPR_WR_ADDR (W_DST_GPR_WR_ADDR_EXE_MDL_IN),
			// | 为解决数据相关问题/读写冲突问题 引入的端口
			// 来自执行模块
			.I_DST_GPR_WR_EN_FROM_EXE_MDL       (W_DST_GPR_WR_EN_GPR_MDL_IN_FROM_EXE_MDL  ), 
			.I_DST_GPR_WR_ADDR_FROM_EXE_MDL     (W_DST_GPR_WR_ADDR_GPR_MDL_IN_FROM_EXE_MDL),
			.I_DST_GPR_WR_DATA_FROM_EXE_MDL     (W_DST_GPR_WR_DATA_GPR_MDL_IN_FROM_EXE_MDL),
			// 来自访存模块
			.I_DST_GPR_WR_EN_FROM_MEM_ACS_MDL   (W_DST_GPR_WR_EN_MEM_MDL_IN  ), 
			.I_DST_GPR_WR_ADDR_FROM_MEM_ACS_MDL (W_DST_GPR_WR_ADDR_MEM_MDL_IN),
			.I_DST_GPR_WR_DATA_FROM_MEM_ACS_MDL (W_DST_GPR_WR_DATA_MEM_MDL_IN),
			.I_PAUSE_ACK(W_PAUSE_ACK),
			.O_PAUSE_REQ(W_PAUSE_REQ_FROM_ID_MDL)	
		);
// | 通用寄存器模块例化
	GPR_WR_RD_MDL INST_GPR_WR_RD_MDL
		(
			.I_CPU_CLK       (I_CPU_CLK),
			.I_CPU_RSTN      (I_CPU_RSTN),

			.I_GPR_WR_EN     (W_DST_GPR_WR_EN_GPR_MDL_IN),
			.I_GPR_WR_ADDR   (W_DST_GPR_WR_ADDR_GPR_MDL_IN),
			.I_GPR_WR_DATA   (W_DST_GPR_WR_DATA_GPR_MDL_IN),

			.I_GPR_RD_EN_A   (W_GPR_RD_EN_A),
			.I_GPR_RD_ADDR_A (W_GPR_RD_ADDR_A),
			.O_GPR_RD_DATA_A (W_GPR_RD_DATA_A),
			.I_GPR_RD_EN_B   (W_GPR_RD_EN_B),
			.I_GPR_RD_ADDR_B (W_GPR_RD_ADDR_B),
			.O_GPR_RD_DATA_B (W_GPR_RD_DATA_B)
		);
// | 执行模块例化
	EXE_MDL INST_EXE_MDL
		(
			.I_CPU_CLK         (I_CPU_CLK),
			.I_CPU_RSTN        (I_CPU_RSTN),

			.I_ALU_OP_TYPE     (W_ALU_OP_TYPE),
			.I_SRC_OPR_DATA_A  (W_SRC_OPR_DATA_A),
			.I_SRC_OPR_DATA_B  (W_SRC_OPR_DATA_B),

			.I_DST_GPR_WR_EN   (W_DST_GPR_WR_EN_EXE_MDL_IN),
			.I_DST_GPR_WR_ADDR (W_DST_GPR_WR_ADDR_EXE_MDL_IN),

			.I_HI(W_O_HI),
			.I_LO(W_O_LO),
			.I_HI_FROM_MEM_ACS_MDL		(W_O_EXE_HI),
			.I_LO_FROM_MEM_ACS_MDL		(W_O_EXE_LO),
			.I_WR_EN_FROM_MEM_ACS_MDL   (W_O_EXE_HILO_WR_EN),
			.I_HI_FROM_HI_LO_REG_MDL	(W_HI),
			.I_LO_FROM_HI_LO_REG_MDL	(W_LO),
			.I_WR_EN_FROM_HI_LO_REG_MDL	(W_HILO_WR_EN),

			.O_DST_GPR_WR_EN   (W_DST_GPR_WR_EN_MEM_MDL_IN  ),
			.O_DST_GPR_WR_ADDR (W_DST_GPR_WR_ADDR_MEM_MDL_IN),
			.O_DST_GPR_WR_DATA (W_DST_GPR_WR_DATA_MEM_MDL_IN),
			// | 为解决数据相关问题/读写冲突问题 引入的端口
			// 送至指令译码模块
			.O_DST_GPR_WR_EN_2_ID_MDL   (W_DST_GPR_WR_EN_GPR_MDL_IN_FROM_EXE_MDL  ),  
			.O_DST_GPR_WR_ADDR_2_ID_MDL (W_DST_GPR_WR_ADDR_GPR_MDL_IN_FROM_EXE_MDL),
			.O_DST_GPR_WR_DATA_2_ID_MDL (W_DST_GPR_WR_DATA_GPR_MDL_IN_FROM_EXE_MDL),

			.O_HI(W_O_EXE_HI),
			.O_LO(W_O_EXE_LO),
			.O_HILO_WR_EN(W_O_EXE_HILO_WR_EN),

			.I_PAUSE_ACK(W_PAUSE_ACK),
			.O_PAUSE_REQ(W_PAUSE_REQ_FROM_EXE_MDL)	
		);
// | 存储器存取模块例化
	MEM_ACS_MDL INST_MEM_ACS_MDL
		(
			.I_CPU_CLK         (I_CPU_CLK),
			.I_CPU_RSTN        (I_CPU_RSTN),

			.I_DST_GPR_WR_EN   (W_DST_GPR_WR_EN_MEM_MDL_IN  ),
			.I_DST_GPR_WR_ADDR (W_DST_GPR_WR_ADDR_MEM_MDL_IN),
			.I_DST_GPR_WR_DATA (W_DST_GPR_WR_DATA_MEM_MDL_IN),

			.O_DST_GPR_WR_EN   (W_DST_GPR_WR_EN_GPR_MDL_IN  ),
			.O_DST_GPR_WR_ADDR (W_DST_GPR_WR_ADDR_GPR_MDL_IN),
			.O_DST_GPR_WR_DATA (W_DST_GPR_WR_DATA_GPR_MDL_IN),

			.I_HI				(W_O_EXE_HI),
			.I_LO				(W_O_EXE_LO),
			.I_HILO_WR_EN		(W_O_EXE_HILO_WR_EN),
			
			.O_HI 				(W_HI),
			.O_LO 				(W_LO),
			.O_HILO_WR_EN  		(W_HILO_WR_EN),

			.I_PAUSE_ACK(W_PAUSE_ACK)
			// .O_PAUSE_REQ()	
		);
// | HI LO 寄存器例化
	HI_LO_REG_MDL INST_HI_LO_REG_MDL
		(
			.I_CPU_CLK    (I_CPU_CLK),
			.I_CPU_RSTN   (I_CPU_RSTN),
			.I_HILO_WR_EN (W_HILO_WR_EN),
			.I_HI         (W_HI),
			.I_LO         (W_LO),
			.O_HI         (W_O_HI),
			.O_LO         (W_O_LO)
		);
// | PIPE_LINE_CTRL_MDL 模块例化
	PIPE_LINE_CTRL_MDL INST_PIPE_LINE_CTRL_MDL
		(
			.I_CPU_CLK                (I_CPU_CLK),
			.I_CPU_RSTN               (I_CPU_RSTN),
			.I_PAUSE_REQ_FROM_ID_MDL  (W_PAUSE_REQ_FROM_ID_MDL),
			.I_PAUSE_REQ_FROM_EXE_MDL (W_PAUSE_REQ_FROM_EXE_MDL),
			.O_PAUSE_ACK              (W_PAUSE_ACK)
		);

endmodule

MIPS32 SOPC

// |------------------------------ ================================== ------------------------------
// |============================== 		     MIPS32 SOPC 系统  	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-07
// |Finish Date : 2022-12-07
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-
// |Who :Xu Y. B.
// |What:


`include "MIPS_SYS_DEFINES.v"
`timescale 1ns / 1ps

module TOP_MIPS32_SOPC(

// |--------------------------------------  输入输出端口声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 时钟、复位
input 															I_CPU_CLK,
input 															I_CPU_RSTN

    );
// |--------------------------------------  模块内部信号声明  --------------------------------------
// |------------------------------------------------------------------------------------------------
// | TOP_MIPS32 模块端口
// | 指令取
wire			[`DEF_ISTC_DATA_BUS]							W_ISTC_FROM_ROM;
wire			[`DEF_ISTC_ADDR_BUS]							W_ISTC_ADDR_2_ROM;
// | 指令存储器使能
wire															W_ISTC_ROM_CE;

// |--------------------------------------      子模块例化    --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 处理器模块
	TOP_MIPS32 INST_TOP_MIPS32
		(
			.I_CPU_CLK         (I_CPU_CLK),
			.I_CPU_RSTN        (I_CPU_RSTN),
			.I_ISTC_FROM_ROM   (W_ISTC_FROM_ROM),
			.O_ISTC_ADDR_2_ROM (W_ISTC_ADDR_2_ROM),
			.O_ISTC_ROM_CE     (W_ISTC_ROM_CE)
		);
// | 指令存储模块
	ROM_ISTC_MDL INST_ROM_ISTC_MDL
		(
			.I_CPU_CLK  (I_CPU_CLK),
			.I_CPU_RSTN (I_CPU_RSTN),
			.I_RD_EN    (W_ISTC_ROM_CE),
			.I_RD_ADDR  (W_ISTC_ADDR_2_ROM),
			.O_ISTC     (W_ISTC_FROM_ROM)
		);

endmodule

仿真

仿真程序

.org 0x0 		
.global _start 	
.set noat		

_start:
ori $1,$0,0xFFFF
sll $1,$1,16
ori $1,$1,0xFFFB
ori $2,$0,6
mult $1,$2
madd $1,$2
nop
maddu $1,$2
msub $1,$2
nop
msubu $1,$2
madd $1,$2
maddu $1,$2
nop
msub $1,$2
msubu $1,$2
madd $1,$2
maddu $1,$2
nop
madd $1,$2
maddu $1,$2
msub $1,$2
msubu $1,$2
madd $1,$2
nop

TESTBENCH

// |------------------------------ ================================== ------------------------------
// |============================== 		    顶层模块仿真平台  	      ==============================
// |------------------------------ ================================== ------------------------------
// |Create Date : 2022-12-08
// |Finish Date : 2022-12-08
// |Edited by   : Xu Y. B. (CSDN USER NAME :在路上,正出发)
// |Reference   : 《自己动手写CPU》
// |
// |
// |------------------------------------------------------------------------------------------------
// |---------------------------------------- Change History ----------------------------------------
// |Date:2022-12-
// |Who :Xu Y. B.
// |What:



`timescale 1ns / 1ps
`define 	CLK_PERIOD 		20


module TB_TOP_MIPS32();
reg 						I_CPU_CLK;
reg 						I_CPU_RSTN;
// 产生时钟
initial 	I_CPU_CLK	=	0;
always #(`CLK_PERIOD/2) I_CPU_CLK = ~I_CPU_CLK;
// 产生复位
initial
begin
	I_CPU_RSTN <= 0;
	#(`CLK_PERIOD*3);
	@(posedge I_CPU_CLK);
	I_CPU_RSTN <= 1;
	#(`CLK_PERIOD*50);
	$finish;
end
// 顶层例化
	TOP_MIPS32_SOPC INST_TOP_MIPS32_SOPC 
	(.I_CPU_CLK(I_CPU_CLK), 
	 .I_CPU_RSTN(I_CPU_RSTN)
	);

endmodule

仿真结果



欢迎交流~~~~~

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在路上-正出发

哈哈,多少是个心意

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值