目录
引言
致谢
指令说明
数据相关问题
设计
宏定义
译码模块
执行模块
HI LO寄存器
顶层模块
仿真
仿真代码
仿真结果
随章节进度继续推进,本章继续实现 移动 指令等其他操作指令。
感谢书籍《自己动手写CPU》及其作者雷思磊。一并感谢开源精神。
MIPS32指令集定义了 6条 移动操作指令:
movn、movz、mfhi、mthi、 mflo、mtlo
指令说明:用法说明:
示例:
此处仅给出修改模块的代码:
// |------------------------------ ================================== ------------------------------
// |============================== 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操作功能宏定义
// |-------------------------------------- 系统级全局宏定义 --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 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_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_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_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-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:增加移动指令的译码功能
`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 reg [`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
);
// |-------------------------------------- 模块内部信号声明 --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 指令分解相关
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;
// |-------------------------------------- 模块内部逻辑设计 --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 指令分解相关
assign W_ISTC_TYPE = I_ISTC[31:26];// 指令码
assign W_SRC_GPR_ADDR = I_ISTC[25:21];
assign W_DST_GPR_ADDR = I_ISTC[20:16];
assign W_ISTC_IMM_DATA = I_ISTC[15:0] ;
assign W_ISTC_15_11_BIT = I_ISTC[15:11];
assign W_ISTC_10_6_BIT = I_ISTC[10:6];
assign W_ISTC_5_0_BIT = I_ISTC[5:0];
// | 指令译码
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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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
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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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;
O_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
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;
O_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(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;
O_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;
O_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;
O_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;
O_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:增加移动运算执行功能。
`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
);
// |-------------------------------------- 模块内部信号声明 --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 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;
// |-------------------------------------- 模块内部逻辑设计 --------------------------------------
// |------------------------------------------------------------------------------------------------
// | I_ALU_OP_TYPE 打拍对齐时序
always @ (posedge I_CPU_CLK)
begin
if(~I_CPU_RSTN)
begin
R_I_ALU_OP_TYPE <= 0;
end
else
begin
R_I_ALU_OP_TYPE <= 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
// | 计算单元
// 组合逻辑
always @ (*)
begin
if(~I_CPU_RSTN)
begin
O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
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;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
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;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
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;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
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);
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
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;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
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;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
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);
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
O_LO = `DEF_ZERO_WORD;
end
`DEF_ALU_MOVZ_OPR:
begin
O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_A;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
O_LO = `DEF_ZERO_WORD;
end
`DEF_ALU_MOVN_OPR:
begin
O_DST_GPR_WR_DATA_2_ID_MDL = I_SRC_OPR_DATA_A;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
O_LO = `DEF_ZERO_WORD;
end
`DEF_ALU_MFHI_OPR:
begin
O_DST_GPR_WR_DATA_2_ID_MDL = R_HI;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
O_LO = `DEF_ZERO_WORD;
end
`DEF_ALU_MTHI_OPR:
begin
O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
O_HILO_WR_EN = 1'b1;
O_HI = I_SRC_OPR_DATA_A;
O_LO = R_LO;
end
`DEF_ALU_MFLO_OPR:
begin
O_DST_GPR_WR_DATA_2_ID_MDL = R_LO;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
O_LO = `DEF_ZERO_WORD;
end
`DEF_ALU_MTLO_OPR:
begin
O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
O_HILO_WR_EN = 1'b1;
O_HI = R_HI;
O_LO = I_SRC_OPR_DATA_A;
end
default:
begin
O_DST_GPR_WR_DATA_2_ID_MDL = `DEF_ZERO_WORD;
O_HILO_WR_EN = 1'b0;
O_HI = `DEF_ZERO_WORD;
O_LO = `DEF_ZERO_WORD;
end
endcase
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
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
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
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;
endmodule
// |------------------------------ ================================== ------------------------------
// |============================== 指令-译码模块 ==============================
// |------------------------------ ================================== ------------------------------
// |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
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类问题)
// | 顶层文件配合改动
`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;
// |-------------------------------------- 模块内部逻辑设计 --------------------------------------
// |------------------------------------------------------------------------------------------------
// | 输出
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),
.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)
);
// | 通用寄存器模块例化
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)
);
// | 存储器存取模块例化
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)
);
// | 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)
);
endmodule
此处参考课本示例。
.org 0x0
.global _start
.set noat
_start:
lui $1,0x0000
lui $2,0xFFFF
lui $3,0x0505
lui $4,0x0000
movz $4,$2,$1
movn $4,$3,$1
movn $4,$3,$2
movz $4,$2,$3
mthi $0
mthi $2
mthi $3
mfhi $4
mtlo $3
mtlo $2
mtlo $1
mflo $4