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

news/2025/2/12 21:52:11/


 



目录

引言

致谢

流水线暂停

指令说明

madd、maddu、msub、msubu

设计

宏定义文件

程序计数器模块

译码模块

执行模块

访存模块

HI LO 寄存器模块

通用寄存器模块

流水线控制模块

程序ROM

MIPS32顶层

MIPS32 SOPC

仿真

仿真程序

TESTBENCH

仿真结果


 


引言

随章节进度继续推进,本章继续实现 流水线暂停、复杂算术运算(包括乘累加等) 指令等其他操作指令。

本篇文章主要实现简单算术操作指令,一共有15条指令。

致谢

感谢书籍《自己动手写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 / 1psmodule 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)
beginif(~I_CPU_RSTN)beginO_ISTC_ROM_CE <= `DEF_CHIP_DIS;endelsebeginO_ISTC_ROM_CE <= `DEF_CHIP_EN;end
end// PC
always @ (posedge I_CPU_CLK)
beginif((~I_CPU_RSTN) || (O_ISTC_ROM_CE == `DEF_CHIP_DIS))beginO_PC <= 32'd0;endelse if(~I_PC_PAUSE)beginO_PC <= O_PC + 32'd4;endelsebeginO_PC <= O_PC ;end
endendmodule

译码模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     指令-译码模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |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 / 1psmodule 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)
beginif(~I_CPU_RSTN)beginR_PAUSE_REQ <= 2'b00;endelse if(W_ISTC_TYPE == `DEF_ISTC_SPEC2)beginR_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:beginR_PAUSE_REQ[0] <= 1'b1;enddefault:beginR_PAUSE_REQ[0] <= R_PAUSE_REQ[0];endendcaseendelsebeginR_PAUSE_REQ[0] <= R_PAUSE_REQ[0];R_PAUSE_REQ[1] <= R_PAUSE_REQ[0];end
end// | 指令译码 
always @ (posedge I_CPU_CLK)
beginif(~I_CPU_RSTN)beginO_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;endelsebegincase(W_ISTC_TYPE)`DEF_ISTC_SPEC://SPECIAL 类 指令begincase(W_ISTC_10_6_BIT)5'd0:begincase(W_ISTC_5_0_BIT)`DEF_ISTC_AND:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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;// endO_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:beginO_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;// endO_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:beginO_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:beginO_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:beginO_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:beginO_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  :beginO_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 :beginO_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  :beginO_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 :beginO_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  :beginO_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 :beginO_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 :beginO_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:beginO_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:beginO_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;endendcaseenddefault:beginO_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;endendcaseend`DEF_ISTC_SPEC2:begincase(W_ISTC_5_0_BIT)`DEF_ISTC_CLZ:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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 :beginO_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:beginO_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;						enddefault:beginO_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;endendcaseend`DEF_ISTC_ORI:// ori指令beginO_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:beginO_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:beginO_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:beginO_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:beginO_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 :beginO_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:beginO_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 :beginO_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:beginO_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};enddefault:beginO_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;endendcaseif(W_I_ISTC[31:21] == 11'd0)begincase(W_ISTC_5_0_BIT)`DEF_ISTC_SLL:beginO_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:beginO_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:beginO_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};enddefault:beginO_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;endendcaseendend
end// | 数据输出
always @ (posedge I_CPU_CLK)
beginif(~I_CPU_RSTN)beginO_SRC_OPR_DATA_A <= `DEF_ZERO_WORD;endelse 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))beginO_SRC_OPR_DATA_A <= I_DST_GPR_WR_DATA_FROM_EXE_MDL;endelse 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))beginO_SRC_OPR_DATA_A <= I_DST_GPR_WR_DATA_FROM_MEM_ACS_MDL;endelse if(O_GPR_RD_EN_A)beginO_SRC_OPR_DATA_A <= I_GPR_RD_DATA_A;endelse if(~O_GPR_RD_EN_A)beginO_SRC_OPR_DATA_A <= R_IMM_DATA_32BIT;endelsebeginO_SRC_OPR_DATA_A <= `DEF_ZERO_WORD;end
endalways @ (posedge I_CPU_CLK)
beginif(~I_CPU_RSTN)beginO_SRC_OPR_DATA_B <= `DEF_ZERO_WORD;endelse 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))beginO_SRC_OPR_DATA_B <= I_DST_GPR_WR_DATA_FROM_EXE_MDL;endelse 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))beginO_SRC_OPR_DATA_B <= I_DST_GPR_WR_DATA_FROM_MEM_ACS_MDL;endelse if(O_GPR_RD_EN_B)beginO_SRC_OPR_DATA_B <= I_GPR_RD_DATA_B;endelse if(~O_GPR_RD_EN_B)beginO_SRC_OPR_DATA_B <= R_IMM_DATA_32BIT;endelsebeginO_SRC_OPR_DATA_B <= `DEF_ZERO_WORD;end
endendmodule

执行模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     指令-执行模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |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 / 1psmodule 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)
beginif(~I_CPU_RSTN)beginR_I_ALU_OP_TYPE <= 0;endelse if(!I_PAUSE_ACK[2])beginR_I_ALU_OP_TYPE <= I_ALU_OP_TYPE;endelsebeginR_I_ALU_OP_TYPE <= R_I_ALU_OP_TYPE;end
end
// | 判断选择最新的 HI LO 
always @ (*)
beginif(~I_CPU_RSTN)beginR_HI = `DEF_ZERO_WORD;R_LO = `DEF_ZERO_WORD;endelse if(I_WR_EN_FROM_MEM_ACS_MDL)beginR_HI = I_HI_FROM_MEM_ACS_MDL;R_LO = I_LO_FROM_MEM_ACS_MDL;endelse if(I_WR_EN_FROM_HI_LO_REG_MDL)beginR_HI = I_HI_FROM_HI_LO_REG_MDL;R_LO = I_LO_FROM_HI_LO_REG_MDL;endelsebeginR_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 @ (*)
beginif(~I_CPU_RSTN)beginO_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;endelsebegincase(R_I_ALU_OP_TYPE)`DEF_ALU_OR_OPR:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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:beginO_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  :beginif(W_I_SRC_OPR_DATA_A_SIGNED < W_I_SRC_OPR_DATA_B_SIGNED)beginO_DST_GPR_WR_DATA_2_ID_MDL = 32'd1;endelsebeginO_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;endR_O_HILO_WR_EN			   = 1'b0;R_O_HI 					   = `DEF_ZERO_WORD;R_O_LO 					   = `DEF_ZERO_WORD;			end`DEF_ALU_SLTU_OPR :beginif(I_SRC_OPR_DATA_A < I_SRC_OPR_DATA_B)beginO_DST_GPR_WR_DATA_2_ID_MDL = 32'd1;endelsebeginO_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;endR_O_HILO_WR_EN			   = 1'b0;R_O_HI 					   = `DEF_ZERO_WORD;R_O_LO 					   = `DEF_ZERO_WORD;				end`DEF_ALU_SLTI_OPR :beginif(W_I_SRC_OPR_DATA_A_SIGNED < W_I_SRC_OPR_DATA_B_SIGNED)beginO_DST_GPR_WR_DATA_2_ID_MDL = 32'd1;endelsebeginO_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;endR_O_HILO_WR_EN			   = 1'b0;R_O_HI 					   = `DEF_ZERO_WORD;R_O_LO 					   = `DEF_ZERO_WORD;					end`DEF_ALU_SLTIU_OPR:beginif(I_SRC_OPR_DATA_A < I_SRC_OPR_DATA_B)beginO_DST_GPR_WR_DATA_2_ID_MDL = 32'd1;endelsebeginO_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;endR_O_HILO_WR_EN			   = 1'b0;R_O_HI 					   = `DEF_ZERO_WORD;R_O_LO 					   = `DEF_ZERO_WORD;				end`DEF_ALU_ADD_OPR  :beginO_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 :beginO_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  :beginO_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 :beginO_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 :beginO_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:beginO_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  :beginO_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  :beginO_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 :beginO_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:beginO_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  :beginO_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:beginO_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;if(R_2STEP_ISTC_CNT == 1)beginR_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};	endelsebeginR_O_HILO_WR_EN			   = 1'b0;R_O_HI 					   = `DEF_ZERO_WORD;R_O_LO 					   = `DEF_ZERO_WORD;					endend`DEF_ALU_MSUB_OPR ,`DEF_ALU_MSUBU_OPR:beginO_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;if(R_2STEP_ISTC_CNT == 1)beginR_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};endelsebeginR_O_HILO_WR_EN			   = 1'b0;R_O_HI 					   = `DEF_ZERO_WORD;R_O_LO 					   = `DEF_ZERO_WORD;					endenddefault:beginO_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;endendcaseend
end// HI LO 寄存输出
always @ (posedge I_CPU_CLK)
beginif(~I_CPU_RSTN)beginO_HILO_WR_EN <= 1'b0;O_HI 		 <= 32'd0;O_LO 		 <= 32'd0;endelsebeginif(!I_PAUSE_ACK[2])beginO_HILO_WR_EN <= R_O_HILO_WR_EN;O_HI 		 <= R_O_HI 		;O_LO 		 <= R_O_LO 		;	end	elsebeginO_HILO_WR_EN <= 1'b0;O_HI 		 <= 32'd0;O_LO 		 <= 32'd0;			endend
end// | 写操作打拍
always @ (posedge I_CPU_CLK)
beginif(~I_CPU_RSTN)beginO_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;endelsebeginif(!I_PAUSE_ACK[2])beginR_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) beginif(I_SRC_OPR_DATA_B == `DEF_ZERO_WORD)beginO_DST_GPR_WR_EN   <= 1'b1;endelsebeginO_DST_GPR_WR_EN   <= 1'b0;endendelse if(R_I_ALU_OP_TYPE == `DEF_ALU_MOVN_OPR)beginif(I_SRC_OPR_DATA_B == `DEF_ZERO_WORD)beginO_DST_GPR_WR_EN   <= 1'b0;endelsebeginO_DST_GPR_WR_EN   <= 1'b1;endendelse 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)beginO_DST_GPR_WR_EN <= 1'b0;endelsebeginO_DST_GPR_WR_EN <= R_I_DST_GPR_WR_EN;endO_DST_GPR_WR_ADDR <= R_I_DST_GPR_WR_ADDR;O_DST_GPR_WR_DATA <= O_DST_GPR_WR_DATA_2_ID_MDL;endelsebeginO_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;			endend
endassign 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 @ (*)
beginif(~I_CPU_RSTN)beginO_PAUSE_REQ = 1'b0;endelsebegincase(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:beginif(R_2STEP_ISTC_CNT == 0)beginO_PAUSE_REQ = 1'b1;endelse if(R_2STEP_ISTC_CNT == 1)beginO_PAUSE_REQ = 1'b0;endelse beginO_PAUSE_REQ = 1'b1;endenddefault:beginO_PAUSE_REQ = 1'b0;endendcaseend
endalways @ (posedge I_CPU_CLK)
beginif(~I_CPU_RSTN)beginR_2STEP_ISTC_CNT <= 2'd0;endelsebegincase(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:beginif(R_2STEP_ISTC_CNT == 1)beginR_2STEP_ISTC_CNT <= 2'd0;endelsebeginR_2STEP_ISTC_CNT <= R_2STEP_ISTC_CNT + 1;endenddefault:beginR_2STEP_ISTC_CNT <= 2'd0;endendcaseend
endalways @ (posedge I_CPU_CLK)
beginif(~I_CPU_RSTN)beginR_MID_RES_MULT <= 64'd0;endelsebegincase(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:beginif(R_2STEP_ISTC_CNT == 0)beginif(R_I_ALU_OP_TYPE == `DEF_ALU_MADD_OPR || R_I_ALU_OP_TYPE == `DEF_ALU_MSUB_OPR)beginR_MID_RES_MULT <= W_I_SRC_OPR_DATA_A_SIGNED * W_I_SRC_OPR_DATA_B_SIGNED;endelse if(R_I_ALU_OP_TYPE == `DEF_ALU_MADDU_OPR || R_I_ALU_OP_TYPE == `DEF_ALU_MSUBU_OPR)beginR_MID_RES_MULT <= I_SRC_OPR_DATA_A * I_SRC_OPR_DATA_B;endelsebeginR_MID_RES_MULT <= R_MID_RES_MULT;endendelsebeginR_MID_RES_MULT <= R_MID_RES_MULT;endenddefault:beginR_MID_RES_MULT <= 64'd0;endendcaseend
endendmodule

访存模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     -执行模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |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 / 1psmodule 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)
beginif(~I_CPU_RSTN)beginO_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;		endelsebeginif(!I_PAUSE_ACK[3])beginO_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;endelsebeginO_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;				endend
endendmodule

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 / 1psmodule 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)
beginif(~I_CPU_RSTN)beginO_HI <= `DEF_ZERO_WORD;O_LO <= `DEF_ZERO_WORD;endelse if(I_HILO_WR_EN)beginO_HI <= I_HI;O_LO <= I_LO;endelsebeginO_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 / 1psmodule 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)
beginif(I_CPU_RSTN)beginif(I_GPR_WR_EN && I_GPR_WR_ADDR != `DEF_GPR_ADDR_WIDTH'd0)beginR_GPR[I_GPR_WR_ADDR] <= I_GPR_WR_DATA;endend
end// |--------------------------------------    PORT A 读操作   --------------------------------------
// |------------------------------------------------------------------------------------------------
always @ (*)
beginif(~I_CPU_RSTN)beginO_GPR_RD_DATA_A = `DEF_ZERO_WORD;endelse if(I_GPR_WR_EN && I_GPR_RD_EN_A && (I_GPR_RD_ADDR_A == I_GPR_WR_ADDR))beginO_GPR_RD_DATA_A = I_GPR_WR_DATA;endelse if(I_GPR_RD_EN_A)beginO_GPR_RD_DATA_A = R_GPR[I_GPR_RD_ADDR_A];endelsebeginO_GPR_RD_DATA_A = `DEF_ZERO_WORD;end
end// |--------------------------------------    PORT B 读操作   --------------------------------------
// |------------------------------------------------------------------------------------------------
always @ (*)
beginif(~I_CPU_RSTN)beginO_GPR_RD_DATA_B = `DEF_ZERO_WORD;endelse if(I_GPR_WR_EN && I_GPR_RD_EN_B && (I_GPR_RD_ADDR_B == I_GPR_WR_ADDR))beginO_GPR_RD_DATA_B = I_GPR_WR_DATA;endelse if(I_GPR_RD_EN_B)beginO_GPR_RD_DATA_B = R_GPR[I_GPR_RD_ADDR_B];endelsebeginO_GPR_RD_DATA_B = `DEF_ZERO_WORD;end
endendmodule

流水线控制模块

// |------------------------------ ================================== ------------------------------
// |============================== 		     指令-执行模块  	      ==============================
// |------------------------------ ================================== ------------------------------
// |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 @ (*)
beginif(~I_CPU_RSTN)beginO_PAUSE_ACK <= 5'd0;endelse if(I_PAUSE_REQ_FROM_EXE_MDL)beginO_PAUSE_ACK <= 5'b0_0_1_1_1;endelse if(I_PAUSE_REQ_FROM_ID_MDL)beginO_PAUSE_ACK <= 5'b0_0_0_1_1;endelsebeginO_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 / 1psmodule 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)
beginif(~I_CPU_RSTN)beginO_ISTC <= `DEF_ZERO_WORD;endelsebeginif(I_RD_EN)beginO_ISTC <= R_ROM_DATA[I_RD_ADDR[`DEF_ISTC_ADDR_WIDTH_ACTUAL+1:2]];endelsebeginO_ISTC <= `DEF_ZERO_WORD;endend
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 / 1psmodule 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 / 1psmodule 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 		20module 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
beginI_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

仿真结果



欢迎交流~~~~~


http://www.ppmy.cn/news/3672.html

相关文章

ELK (一)部署ELK+Filebeat日志收集分析系统

说明&#xff1a;此安装流程只适用于8.0.0以下的版本 1. ElasticSearch 部署 1.1 下载ElasticSearch的wget指令&#xff1a; wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.4-linux-x86_64.tar.gz1.2 解压安装包到指定目录 指定解压缩到 …

第4篇:嵌入式Linux应用开发基础知识

嵌入式Linux应用开发基础知识一、GCC编译过程二、MakefileMakefile的引入及规则Makefile的语法a. 通配符b. 假想目标: .PHONYC. 变量Makefile函数函数foreach函数filter/filter-outWildcardpatsubst函数Makefile实例通用MakefikeMakefikeMakefile.build说明.txt三、TCPserver.c…

[附源码]Python计算机毕业设计Django架构的博客平台设计

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;我…

深度学习——使用图像增广进行训练CIFAR10代码

1.训练数据样本进行增广使用简单的随机左右翻转&#xff0c;预测过程不使用随机图像增广。 使用ToTensor将图像转换为框架所需格式。形状为&#xff08;批量大小&#xff0c;通道数&#xff0c;高度&#xff0c;宽度&#xff09;的32位浮点数&#xff0c;取值范围为0&#xff…

Docker Swarm介绍及使用入门

一、Swarm介绍 Docker Swarm是管理跨节点容器的编排工具&#xff0c;相较于Docker Compose而言&#xff0c;Compose只能编排单节点上的容器&#xff0c;Swarm将一群Docker节点虚拟化为一个主机&#xff0c;使得用户只要在单一主机上操作就能完成对整个容器集群的管理工作。如果…

docker中的c++ ROS节点中使用Matplotlib-cpp

背景 有时debug算法问题&#xff0c;想把算法&#xff0c;代码的中间量快速可视化出来&#xff0c;目前采用rviz或者qt_ros可以实现&#xff0c;但都不是很方便&#xff0c;代码开发量较大&#xff0c;常常会想要是能在ros c中也能像Matlab一样直接plot绘图就好了&#xff0c;…

大数据Kudu(六):Kudu Java Api操作

文章目录 ​​​​​​Kudu Java Api操作 一、​​​​​​​​​​​​​​添加Maven依赖

关于git,你需要了解这些

Introduction 该文档用于汇总一些git的常用操作及开发规范&#xff0c;持续更新中… References 整理项目开发中git三种常用的操作方式 -zeeblogGit使用 从入门到入土 收藏吃灰系列 (八) 什么是分支 分支的作用十分钟学会正确的github工作流&#xff0c;和开源作者们使用同一…