实验3:CUP的译码ID阶段实现

ID阶段(Instruction Decode)

ID阶段对指令进行解码并生成必要的信号。数据的直通、Load冒险的检测,分支的判定都在这个阶段进行

各模块和端口定义:

1.指令解码器 decoder:
    /********** IF/ID pipeline register **********/
	input  wire [`WordAddrBus]	 if_pc,			 // Program counter
	input  wire [`WordDataBus]	 if_insn,		 // Instruction
	input  wire					 if_en,			 // Enable pipeline data
	/********** GPR interface **********/
	input  wire [`WordDataBus]	 gpr_rd_data_0, // Read data 0
	input  wire [`WordDataBus]	 gpr_rd_data_1, // Read data 1
	output wire [`RegAddrBus]	 gpr_rd_addr_0, // Read address 0
	output wire [`RegAddrBus]	 gpr_rd_addr_1, // Read address 1
	/********** Forwarding **********/
	// Forwarding form ID stage
	input  wire					 id_en,			// Enable pipeline data
	input  wire [`RegAddrBus]	 id_dst_addr,	// Write address
	input  wire					 id_gpr_we_,	// Write enable
	input  wire [`MemOpBus]		 id_mem_op,		// Memory operation
	// Forwarding form EX stage
	input  wire					 ex_en,			// Enable pipeline data
	input  wire [`RegAddrBus]	 ex_dst_addr,	// Write address
	input  wire					 ex_gpr_we_,	// Write enable
	input  wire [`WordDataBus]	 ex_fwd_data,	// Forwarding data
	// Forwarding form MEM stage
	input  wire [`WordDataBus]	 mem_fwd_data,	// Forwarding data
	/********** Control register interface **********/
	input  wire [`CpuExeModeBus] exe_mode,		// Execution mode
	input  wire [`WordDataBus]	 creg_rd_data,	// Read data
	output wire [`RegAddrBus]	 creg_rd_addr,	// Read address
	/********** Decode result **********/
	output reg	[`AluOpBus]		 alu_op,		// ALU operation
	output reg	[`WordDataBus]	 alu_in_0,		// ALU input 0
	output reg	[`WordDataBus]	 alu_in_1,		// ALU input 1
	output reg	[`WordAddrBus]	 br_addr,		// Branch address
	output reg					 br_taken,		// Branch taken
	output reg					 br_flag,		// Brach flag
	output reg	[`MemOpBus]		 mem_op,		// Memory operation
	output wire [`WordDataBus]	 mem_wr_data,	// Data to write to memory
	output reg	[`CtrlOpBus]	 ctrl_op,		// Control operation
	output reg	[`RegAddrBus]	 dst_addr,		// GPR write address
	output reg					 gpr_we_,		// GPR write enable
	output reg	[`IsaExpBus]	 exp_code,		// Exception code
	output reg					 ld_hazard		// Load hazard

2.ID阶段寄存器 id_reg
     /********** Clock & Reset **********/
	input  wire				   clk,			   
	input  wire				   reset,
	/********** Decode result **********/
	input  wire [`AluOpBus]	   alu_op,		   // ALU operation        位宽4
	input  wire [`WordDataBus] alu_in_0,	   // ALU input 0         ALU输入0 位宽32
	input  wire [`WordDataBus] alu_in_1,	   // ALU input 1         ALU输入1 位宽32
	input  wire				   br_flag,		   // Branch flag          分支符号位
	input  wire [`MemOpBus]	   mem_op,		   // Memory operation     位宽2
	input  wire [`WordDataBus] mem_wr_data,	   // Data to write to memory   32
	input  wire [`CtrlOpBus]   ctrl_op,		   // Control operation         2   
	input  wire [`RegAddrBus]  dst_addr,	   // GPR write address         5
	input  wire				   gpr_we_,		   // GPR register write enable    
	input  wire [`IsaExpBus]   exp_code,	   // Exception code  3
	/********** Pipeline control signal **********/
	input  wire				   stall,		   // Stall
	input  wire				   flush,		   // Flush
	/********** IF/ID pipeline register **********/
	input  wire [`WordAddrBus] if_pc,		   // Program counter
	input  wire				   if_en,		   // Enable pipeline data
	/********** ID/EX pipeline register **********/
	output reg	[`WordAddrBus] id_pc,		   // Program counter
	output reg				   id_en,		   // Enable pipeline data
	output reg	[`AluOpBus]	   id_alu_op,	   // ALU operation
	output reg	[`WordDataBus] id_alu_in_0,	   // ALU input 0
	output reg	[`WordDataBus] id_alu_in_1,	   // ALU input 1
	output reg				   id_br_flag,	   // Branch flag
	output reg	[`MemOpBus]	   id_mem_op,	   // Memory operation
	output reg	[`WordDataBus] id_mem_wr_data, // Data to write to memory
	output reg	[`CtrlOpBus]   id_ctrl_op,	   // Control operation
	output reg	[`RegAddrBus]  id_dst_addr,	   // GPR write address
	output reg				   id_gpr_we_,	   // GPR register write enable
	output reg [`IsaExpBus]	   id_exp_code	   // Exception code

3.top模块id_stage:
    /********** Clock & Reset **********/
    input wire clk,
    input wire reset,
    /********** GPR interface **********/
	input  wire [`WordDataBus]	 gpr_rd_data_0,	 // Read data 0
	input  wire [`WordDataBus]	 gpr_rd_data_1,	 // Read data 1
	output wire [`RegAddrBus]	 gpr_rd_addr_0,	 // Read Address 0
	output wire [`RegAddrBus]	 gpr_rd_addr_1,	 // Read Address 1
    /********** Forwarding **********/
	// Forwarding from EX stage
	input  wire					 ex_en,			// Enable pipeline data
	input  wire [`WordDataBus]	 ex_fwd_data,	 // Forwarding data
	input  wire [`RegAddrBus]	 ex_dst_addr,	 // Write address
	input  wire					 ex_gpr_we_,	 // Write enable
    // Forwarding from MEM stage
	input  wire [`WordDataBus]	 mem_fwd_data,	 // Forwarding
	/********** Control register interface **********/
	input  wire [`CpuExeModeBus] exe_mode,		 // Execution mode
	input  wire [`WordDataBus]	 creg_rd_data,	 // Read data
	output wire [`RegAddrBus]	 creg_rd_addr,	 // Read address
	/********** Pipeline control signal **********/
	input  wire					 stall,			 
	input  wire					 flush,			 
	output wire [`WordAddrBus]	 br_addr,		 // Branch address
	output wire					 br_taken,		 // Branch taken
	output wire					 ld_hazard,		 // Load hazard
    
    /********** IF/ID pipeline register **********/
	input  wire [`WordAddrBus]	 if_pc,			 // Program counter
	input  wire [`WordDataBus]	 if_insn,		 // Instruction
	input  wire					 if_en,			 // Enable pipeline data
	/********** ID/EX pipeline register **********/
	output wire [`WordAddrBus]	 id_pc,			 // Program counter
	output wire					 id_en,			 // Enable pipeline data
	output wire [`AluOpBus]		 id_alu_op,		 // ALU operation
	output wire [`WordDataBus]	 id_alu_in_0,	 // ALU input 0
	output wire [`WordDataBus]	 id_alu_in_1,	 // ALU input 1
	output wire					 id_br_flag,	 // Branch flag
	output wire [`MemOpBus]		 id_mem_op,		 // Memory opeartion
	output wire [`WordDataBus]	 id_mem_wr_data, // Data to write to memory
	output wire [`CtrlOpBus]	 id_ctrl_op,	 // Control operation
	output wire [`RegAddrBus]	 id_dst_addr,	 // GPR write address
	output wire					 id_gpr_we_,	 // GPR write enable
	output wire [`IsaExpBus]	 id_exp_code	 // Exception code
   
4.gpr:
    //时钟和复位
    input wire clk,
    input wire reset,
    /********** 读端口0 **********/
	input  wire [`RegAddrBus]  rd_addr_0,		   // Read address 位宽5
	output wire [`WordDataBus] rd_data_0,		   // Read data  位宽32
	/********** 读端口1 **********/
	input  wire [`RegAddrBus]  rd_addr_1,		   // Read address 位宽5
	output wire [`WordDataBus] rd_data_1,		   // Read data 位宽32
	/********** 写端口 **********/
	input  wire				   we_,				   // Write enable 位宽1
	input  wire [`RegAddrBus]  wr_addr,			   // Write address 位宽5
	input  wire [`WordDataBus] wr_data			   // Write data  位宽32

    );
    

1.指令解码器

指令解码器从输入的指令码中分解各个指令字段(从IF阶段拿出的指令),生成地址、数据和控制等信号。数据的直通、Load冒险检测、分支的判断也在这个模块实现。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/01/29 21:41:13
// Design Name: 
// Module Name: decoder
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
//  Instruction decoder
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"

/********** Local header **********/
`include "isa.vh"
`include "cpu.vh"


module decoder(
    /********** IF/ID pipeline register **********/
	input  wire [`WordAddrBus]	 if_pc,			 // Program counter
	input  wire [`WordDataBus]	 if_insn,		 // Instruction
	input  wire					 if_en,			 // Enable pipeline data
	/********** GPR interface **********/
	input  wire [`WordDataBus]	 gpr_rd_data_0, // Read data 0
	input  wire [`WordDataBus]	 gpr_rd_data_1, // Read data 1
	output wire [`RegAddrBus]	 gpr_rd_addr_0, // Read address 0
	output wire [`RegAddrBus]	 gpr_rd_addr_1, // Read address 1
	/********** Forwarding **********/
	// Forwarding form ID stage
	input  wire					 id_en,			// Enable pipeline data
	input  wire [`RegAddrBus]	 id_dst_addr,	// Write address
	input  wire					 id_gpr_we_,	// Write enable
	input  wire [`MemOpBus]		 id_mem_op,		// Memory operation
	// Forwarding form EX stage
	input  wire					 ex_en,			// Enable pipeline data
	input  wire [`RegAddrBus]	 ex_dst_addr,	// Write address
	input  wire					 ex_gpr_we_,	// Write enable
	input  wire [`WordDataBus]	 ex_fwd_data,	// Forwarding data
	// Forwarding form MEM stage
	input  wire [`WordDataBus]	 mem_fwd_data,	// Forwarding data
	/********** Control register interface **********/
	input  wire [`CpuExeModeBus] exe_mode,		// Execution mode
	input  wire [`WordDataBus]	 creg_rd_data,	// Read data
	output wire [`RegAddrBus]	 creg_rd_addr,	// Read address
	/********** Decode result **********/
	output reg	[`AluOpBus]		 alu_op,		// ALU operation
	output reg	[`WordDataBus]	 alu_in_0,		// ALU input 0
	output reg	[`WordDataBus]	 alu_in_1,		// ALU input 1
	output reg	[`WordAddrBus]	 br_addr,		// Branch address
	output reg					 br_taken,		// Branch taken
	output reg					 br_flag,		// Brach flag
	output reg	[`MemOpBus]		 mem_op,		// Memory operation
	output wire [`WordDataBus]	 mem_wr_data,	// Data to write to memory
	output reg	[`CtrlOpBus]	 ctrl_op,		// Control operation
	output reg	[`RegAddrBus]	 dst_addr,		// GPR write address
	output reg					 gpr_we_,		// GPR write enable
	output reg	[`IsaExpBus]	 exp_code,		// Exception code
	output reg					 ld_hazard		// Load hazard

    );
    /********** Instruction field **********/
   // `define IsaOpLoc		   31:26 // Opcode location
   //`define IsaOpBus		   5:0	 // Opcode bus
	wire [`IsaOpBus]	op		= if_insn[`IsaOpLoc];	  // Opcode 指令前六位取出
    //`define IsaRaAddrLoc	   25:21// Register Ra location
    //`define IsaRegAddrBus	   4:0	 // Register address bus
	wire [`RegAddrBus]	ra_addr = if_insn[`IsaRaAddrLoc]; // Ra address
	//$display("ra_addr=%b",ra_addr);
	//`define IsaRbAddrLoc	   20:16 // Register Rb location
	
	wire [`RegAddrBus]	rb_addr = if_insn[`IsaRbAddrLoc]; // Rb address
	//`define IsaRcAddrLoc	   15:11 // Register Rc location
	
	wire [`RegAddrBus]	rc_addr = if_insn[`IsaRcAddrLoc]; // Rc address
	//`define IsaImmLoc		   15:0
	//`define IsaImmBus		   15:0	
	wire [`IsaImmBus]	imm		= if_insn[`IsaImmLoc];	  // Immediate
   
    /********** Immediate **********/
	// Sign extension
	//`define ISA_IMM_MSB		   15	 // Immediate MSB
	//`define WordDataBus			31:0	 	 // Data bus
	//`define ISA_EXT_W		   16
	wire [`WordDataBus] imm_s = {{`ISA_EXT_W{imm[`ISA_IMM_MSB]}}, imm}; //16位立即数扩展到32
	// Zero extension
	wire [`WordDataBus] imm_u = {{`ISA_EXT_W{1'b0}}, imm};
	
	/********** Register read address **********/
	assign gpr_rd_addr_0 = ra_addr; // GPR read address 0
	assign gpr_rd_addr_1 = rb_addr; // GPR read address 1
	assign creg_rd_addr	 = ra_addr; // Control register read address
	
	
	/********** Control register read data **********/
	//`define WordDataBus			31:0	 	 // Data bus
	reg			[`WordDataBus]	ra_data;						  // Unsigned Ra
	wire signed [`WordDataBus]	s_ra_data = $signed(ra_data);	  // Signed Ra
	reg			[`WordDataBus]	rb_data;						  // Unsigned Rb
	wire signed [`WordDataBus]	s_rb_data = $signed(rb_data);	  // Signed Rb
	assign mem_wr_data = rb_data; // Data to write to memory
    
    /********** Address **********/
    //`define WordAddrBus			29:0	 // Address bus
    //`define WORD_ADDR_MSB		29		 // Most significant bit
    //`define WordAddrLoc			31:2	 // Word address location
    //jr_target为字编址, ra_data为字节编址,所以选取ra_data的高30
	wire [`WordAddrBus] ret_addr  = if_pc + 1'b1;					 // Return address
	wire [`WordAddrBus] br_target = if_pc + imm_s[`WORD_ADDR_MSB:0]; // Branch address
	wire [`WordAddrBus] jr_target = ra_data[`WordAddrLoc];		   // Jump address
  
  
   /********** Forwarding **********/
	always @(*) begin
	        $display("op=%b",op);
	       $display("ra_addr=%b",ra_addr);
	       $display("rb_addr=%b",rb_addr);
	       $display("rc_addr=%b",rc_addr);
		/* Ra register */
		if ((id_en == `ENABLE) && (id_gpr_we_ == `ENABLE_) && 
			(id_dst_addr == ra_addr)) begin
			ra_data = ex_fwd_data;	 // Forwarding from EX stage
		end else if ((ex_en == `ENABLE) && (ex_gpr_we_ == `ENABLE_) && 
					 (ex_dst_addr == ra_addr)) begin
			ra_data = mem_fwd_data;	 // Forwarding from MEM stage
		end else begin
			ra_data = gpr_rd_data_0; // Read from register file
			$display("ra_data=%b",ra_data);
		end
		/* Rb register */
		if ((id_en == `ENABLE) && (id_gpr_we_ == `ENABLE_) && 
			(id_dst_addr == rb_addr)) begin
			rb_data = ex_fwd_data;	 // Forwarding from EX stage
		end else if ((ex_en == `ENABLE) && (ex_gpr_we_ == `ENABLE_) && 
					 (ex_dst_addr == rb_addr)) begin
			rb_data = mem_fwd_data;	 // Forwarding from MEM stage
		end else begin
			rb_data = gpr_rd_data_1; // Read from register file
			$display("rb_data=%b",rb_data);
		end
	end 
	
	/********** Load hazard detection **********/
	//`define MEM_OP_LDW			 2'h1 // Read word
	always @(*) begin
		if ((id_en == `ENABLE) && (id_mem_op == `MEM_OP_LDW) &&
			((id_dst_addr == ra_addr) || (id_dst_addr == rb_addr))) begin
			ld_hazard = `ENABLE;  // Load hazard
		end else begin
			ld_hazard = `DISABLE; // No hazard
		end
	end
	
	/********** Decode instruction **********/
	always @(*) begin
		/* Default value */
		alu_op	 = `ALU_OP_NOP;                //ALU操作
		alu_in_0 = ra_data;                   //ALU输入0
		alu_in_1 = rb_data;                   //ALU输入1
		br_taken = `DISABLE;                  //分支成立
		br_flag	 = `DISABLE;                  //分支标志位
		br_addr	 = {`WORD_ADDR_W{1'b0}};      //分支地址
		mem_op	 = `MEM_OP_NOP;               //内存操作
		ctrl_op	 = `CTRL_OP_NOP;              //控制操作
		dst_addr = rb_addr;                   //通用寄存器写入地址
		gpr_we_	 = `DISABLE_;                 //通用寄存器写入有效
		exp_code = `ISA_EXP_NO_EXP;           //异常代码
                                                //`define ISA_EXP_NO_EXP	   3'h0	 // No exception
        /*
        `define ALU_OP_NOP			 4'h0 // No Operation
        `define ALU_OP_AND			 4'h1 // AND
        `define ALU_OP_OR			 4'h2 // OR
        `define ALU_OP_XOR			 4'h3 // XOR
        `define ALU_OP_ADDS			 4'h4 // Signed ADD
        `define ALU_OP_ADDU			 4'h5 // Unsigned ADD
        `define ALU_OP_SUBS			 4'h6 // Signed SUB
        `define ALU_OP_SUBU			 4'h7 // Unsigned SUB
        `define ALU_OP_SHRL			 4'h8 // Shift right
        `define ALU_OP_SHLL			 4'h9 // Shift left
        
        */

        /* Opcode */
		if (if_en == `ENABLE) begin           //流水线数据有效
			case (op)
				/* Logical operation 逻辑运算指令*/
				`ISA_OP_ANDR  : begin        //寄存器间的逻辑与
					alu_op	 = `ALU_OP_AND;  //ALU操作
					dst_addr = rc_addr;     //通用寄存器写入地址
					gpr_we_	 = `ENABLE_;    //通用寄存器写入有效
				end
				`ISA_OP_ANDI  : begin       //寄存器与立即数的逻辑与
					alu_op	 = `ALU_OP_AND;
					alu_in_1 = imm_u;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_ORR	  : begin            //寄存器之间的逻辑或
					alu_op	 = `ALU_OP_OR;
					dst_addr = rc_addr;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_ORI	  : begin           //寄存器与立即数的逻辑或
					alu_op	 = `ALU_OP_OR;
					alu_in_1 = imm_u;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_XORR  : begin           //寄存器间的逻辑异或  
					alu_op	 = `ALU_OP_XOR;
					dst_addr = rc_addr;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_XORI  : begin 
					alu_op	 = `ALU_OP_XOR;      //寄存器与立即数的逻辑异或
					alu_in_1 = imm_u;
					gpr_we_	 = `ENABLE_;
				end
				
				
				/* Arithmetic operation 算术运算指令*/
				`ISA_OP_ADDSR : begin  //寄存器间的有符号运算
					alu_op	 = `ALU_OP_ADDS;
					dst_addr = rc_addr;
					gpr_we_	 = `ENABLE_;
					$display("alu_op=%b",alu_op);
					$display("dst_addr=%b",dst_addr);
					$display("gpr_we_=%b",gpr_we_);
					
					
				end
				`ISA_OP_ADDSI : begin  //寄存器与立即数之间的有符号运算
					alu_op	 = `ALU_OP_ADDS;
					alu_in_1 = imm_s;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_ADDUR : begin  //寄存器间的无符号运算
					alu_op	 = `ALU_OP_ADDU;
					dst_addr = rc_addr;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_ADDUI : begin  //寄存器与立即数之间的无符号运算
					alu_op	 = `ALU_OP_ADDU;
					alu_in_1 = imm_s;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_SUBSR : begin  //寄存器间的有符号减法
					alu_op	 = `ALU_OP_SUBS;
					dst_addr = rc_addr;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_SUBUR : begin  //寄存器的无符号减法
					alu_op	 = `ALU_OP_SUBU;
					dst_addr = rc_addr;
					gpr_we_	 = `ENABLE_;
				end
				
				/* Shift 移位指令*/
				`ISA_OP_SHRLR : begin  //寄存器的逻辑右移
					alu_op	 = `ALU_OP_SHRL;
					dst_addr = rc_addr;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_SHRLI : begin  //寄存器与立即数间的逻辑右移
					alu_op	 = `ALU_OP_SHRL;
					alu_in_1 = imm_u;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_SHLLR : begin   //寄存器间的逻辑左移
					alu_op	 = `ALU_OP_SHLL;
					dst_addr = rc_addr;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_SHLLI : begin  //寄存器与立即数间的逻辑左移
					alu_op	 = `ALU_OP_SHLL;
					alu_in_1 = imm_u;
					gpr_we_	 = `ENABLE_;
				end
				
				
				/* Branch  分支指令*/
				`ISA_OP_BE	  : begin // Signed compare registers(Ra == Rb)
					br_addr	 = br_target;
					br_taken = (ra_data == rb_data) ? `ENABLE : `DISABLE;
					br_flag	 = `ENABLE;
				end
				`ISA_OP_BNE	  : begin // Signed compare registers(Ra != Rb)
					br_addr	 = br_target;
					br_taken = (ra_data != rb_data) ? `ENABLE : `DISABLE;
					br_flag	 = `ENABLE;
				end
				`ISA_OP_BSGT  : begin // Signed compare registers(Ra < Rb)
					br_addr	 = br_target;
					br_taken = (s_ra_data < s_rb_data) ? `ENABLE : `DISABLE;
					br_flag	 = `ENABLE;
				end
				`ISA_OP_BUGT  : begin // Unsigned compare registers(Ra < Rb)
					br_addr	 = br_target;
					br_taken = (ra_data < rb_data) ? `ENABLE : `DISABLE;
					br_flag	 = `ENABLE;
				end
				`ISA_OP_JMP	  : begin // Jump
					br_addr	 = jr_target;
					br_taken = `ENABLE;
					br_flag	 = `ENABLE;
				end
				`ISA_OP_CALL  : begin // Call
					alu_in_0 = {ret_addr, {`BYTE_OFFSET_W{1'b0}}};
					br_addr	 = jr_target;
					br_taken = `ENABLE;
					br_flag	 = `ENABLE;
					dst_addr = `REG_ADDR_W'd31;//CALL指令返回地址写入31号寄存器
					gpr_we_	 = `ENABLE_;
				end
				
				
				/* Memory access 内存访问指令 */
				`ISA_OP_LDW	  : begin // Load word字读取,从内存读取一个字数据存入寄存器中
					alu_op	 = `ALU_OP_ADDU;
					alu_in_1 = imm_s;
					mem_op	 = `MEM_OP_LDW;
					gpr_we_	 = `ENABLE_;
				end
				`ISA_OP_STW	  : begin // Store word 字写入。寄存器中的一个字写入内存中
					alu_op	 = `ALU_OP_ADDU;
					alu_in_1 = imm_s;
					mem_op	 = `MEM_OP_STW;
				end
			
			
				/* System call  特殊指令解码*/
				`ISA_OP_TRAP  : begin // Trap
					exp_code = `ISA_EXP_TRAP;
				end
				//define ISA_EXP_TRAP	   3'h5	 // Trap
				
				/* Privilege 特权指令解码 */
				/*
				// Opcode
                    `define CTRL_OP_NOP			 2'h0 // No Operation
                    `define CTRL_OP_WRCR		 2'h1 // Write to control register
                    `define CTRL_OP_EXRT		 2'h2 // Restore from exception
				*/
				
				`ISA_OP_RDCR  : begin // Read control register  读取控制寄存器
					if (exe_mode == `CPU_KERNEL_MODE) begin
						alu_in_0 = creg_rd_data;
						gpr_we_	 = `ENABLE_;
					end else begin
						exp_code = `ISA_EXP_PRV_VIO;
					end
				end
				`ISA_OP_WRCR  : begin // Write control register  写入控制寄存器
					if (exe_mode == `CPU_KERNEL_MODE) begin 
						ctrl_op	 = `CTRL_OP_WRCR;
					end else begin
						exp_code = `ISA_EXP_PRV_VIO;
					end
				end
				`ISA_OP_EXRT  : begin // Restore from exception 从异常恢复
					if (exe_mode == `CPU_KERNEL_MODE) begin
						ctrl_op	 = `CTRL_OP_EXRT;
					end else begin
						exp_code = `ISA_EXP_PRV_VIO;
					end
				end
				
				
				
				/* Other instructions 其他指令 */
				default		  : begin // Undefined instruction 未定义指令处理
					exp_code = `ISA_EXP_UNDEF_INSN;
				end
			endcase
		end
	end
  
endmodule

2.ID阶段流水线寄存器

主要实现将解码结果输出。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/01/28 10:07:04
// Design Name: 
// Module Name: id_reg
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// ID stage pipeline register
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"

/********** Local header **********/
`include "isa.vh"
`include "cpu.vh"

module id_reg(
    /********** Clock & Reset **********/
	input  wire				   clk,			   
	input  wire				   reset,
	/********** Decode result **********/
	input  wire [`AluOpBus]	   alu_op,		   // ALU operation        位宽4
	input  wire [`WordDataBus] alu_in_0,	   // ALU input 0         ALU输入0 位宽32
	input  wire [`WordDataBus] alu_in_1,	   // ALU input 1         ALU输入1 位宽32
	input  wire				   br_flag,		   // Branch flag          分支符号位
	input  wire [`MemOpBus]	   mem_op,		   // Memory operation     位宽2
	input  wire [`WordDataBus] mem_wr_data,	   // Data to write to memory   32
	input  wire [`CtrlOpBus]   ctrl_op,		   // Control operation         2   
	input  wire [`RegAddrBus]  dst_addr,	   // GPR write address         5
	input  wire				   gpr_we_,		   // GPR register write enable    
	input  wire [`IsaExpBus]   exp_code,	   // Exception code  3
	/********** Pipeline control signal **********/
	input  wire				   stall,		   // Stall
	input  wire				   flush,		   // Flush
	/********** IF/ID pipeline register **********/
	input  wire [`WordAddrBus] if_pc,		   // Program counter
	input  wire				   if_en,		   // Enable pipeline data
	/********** ID/EX pipeline register **********/
	output reg	[`WordAddrBus] id_pc,		   // Program counter
	output reg				   id_en,		   // Enable pipeline data
	output reg	[`AluOpBus]	   id_alu_op,	   // ALU operation
	output reg	[`WordDataBus] id_alu_in_0,	   // ALU input 0
	output reg	[`WordDataBus] id_alu_in_1,	   // ALU input 1
	output reg				   id_br_flag,	   // Branch flag
	output reg	[`MemOpBus]	   id_mem_op,	   // Memory operation
	output reg	[`WordDataBus] id_mem_wr_data, // Data to write to memory
	output reg	[`CtrlOpBus]   id_ctrl_op,	   // Control operation
	output reg	[`RegAddrBus]  id_dst_addr,	   // GPR write address
	output reg				   id_gpr_we_,	   // GPR register write enable
	output reg [`IsaExpBus]	   id_exp_code	   // Exception code

    );
    /********** Pipeline register **********/
	always @(posedge clk or `RESET_EDGE reset) begin
		if (reset == `RESET_ENABLE) begin 
			/* Asynchronous Reset */
			id_pc		   <= #1 `WORD_ADDR_W'h0;
			id_en		   <= #1 `DISABLE;
			id_alu_op	   <= #1 `ALU_OP_NOP;
			id_alu_in_0	   <= #1 `WORD_DATA_W'h0;
			id_alu_in_1	   <= #1 `WORD_DATA_W'h0;
			id_br_flag	   <= #1 `DISABLE;
			id_mem_op	   <= #1 `MEM_OP_NOP;
			id_mem_wr_data <= #1 `WORD_DATA_W'h0;
			id_ctrl_op	   <= #1 `CTRL_OP_NOP;
			id_dst_addr	   <= #1 `REG_ADDR_W'd0;
			id_gpr_we_	   <= #1 `DISABLE_;
			id_exp_code	   <= #1 `ISA_EXP_NO_EXP;
			end
		else begin
		      /* Update pipeline register */
			if (stall == `DISABLE) begin 
				if (flush == `ENABLE) begin // Flush
				   id_pc		  <= #1 `WORD_ADDR_W'h0;
				   id_en		  <= #1 `DISABLE;
				   id_alu_op	  <= #1 `ALU_OP_NOP;
				   id_alu_in_0	  <= #1 `WORD_DATA_W'h0;
				   id_alu_in_1	  <= #1 `WORD_DATA_W'h0;
				   id_br_flag	  <= #1 `DISABLE;
				   id_mem_op	  <= #1 `MEM_OP_NOP;
				   id_mem_wr_data <= #1 `WORD_DATA_W'h0;
				   id_ctrl_op	  <= #1 `CTRL_OP_NOP;
				   id_dst_addr	  <= #1 `REG_ADDR_W'd0;
				   id_gpr_we_	  <= #1 `DISABLE_;
				   id_exp_code	  <= #1 `ISA_EXP_NO_EXP;
				end else begin	
				   id_pc		  <= #1 if_pc;
				   id_en		  <= #1 if_en;
				   id_alu_op	  <= #1 alu_op;
				   id_alu_in_0	  <= #1 alu_in_0;
				   id_alu_in_1	  <= #1 alu_in_1;
				   id_br_flag	  <= #1 br_flag;
				   id_mem_op	  <= #1 mem_op;
				   id_mem_wr_data <= #1 mem_wr_data;
				   id_ctrl_op	  <= #1 ctrl_op;
				   id_dst_addr	  <= #1 dst_addr;
				   id_gpr_we_	  <= #1 gpr_we_;
				   id_exp_code	  <= #1 exp_code;
				end	
			end
		end
end	
    
endmodule

3.top模块(连接各模块)

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/02/02 16:21:32
// Design Name: 
// Module Name: id_stage
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// ID stage --TOP顶层模块
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"

/********** Local header **********/
`include "isa.vh"
`include "cpu.vh"



module id_stage(
    /********** Clock & Reset **********/
    input wire clk,
    input wire reset,
    /********** GPR interface **********/
	input  wire [`WordDataBus]	 gpr_rd_data_0,	 // Read data 0
	input  wire [`WordDataBus]	 gpr_rd_data_1,	 // Read data 1
	output wire [`RegAddrBus]	 gpr_rd_addr_0,	 // Read Address 0
	output wire [`RegAddrBus]	 gpr_rd_addr_1,	 // Read Address 1
    /********** Forwarding **********/
	// Forwarding from EX stage
	input  wire					 ex_en,			// Enable pipeline data
	input  wire [`WordDataBus]	 ex_fwd_data,	 // Forwarding data
	input  wire [`RegAddrBus]	 ex_dst_addr,	 // Write address
	input  wire					 ex_gpr_we_,	 // Write enable
    // Forwarding from MEM stage
	input  wire [`WordDataBus]	 mem_fwd_data,	 // Forwarding
	/********** Control register interface **********/
	input  wire [`CpuExeModeBus] exe_mode,		 // Execution mode
	input  wire [`WordDataBus]	 creg_rd_data,	 // Read data
	output wire [`RegAddrBus]	 creg_rd_addr,	 // Read address
	/********** Pipeline control signal **********/
	input  wire					 stall,			 
	input  wire					 flush,			 
	output wire [`WordAddrBus]	 br_addr,		 // Branch address
	output wire					 br_taken,		 // Branch taken
	output wire					 ld_hazard,		 // Load hazard
    
    /********** IF/ID pipeline register **********/
	input  wire [`WordAddrBus]	 if_pc,			 // Program counter
	input  wire [`WordDataBus]	 if_insn,		 // Instruction
	input  wire					 if_en,			 // Enable pipeline data
	/********** ID/EX pipeline register **********/
	output wire [`WordAddrBus]	 id_pc,			 // Program counter
	output wire					 id_en,			 // Enable pipeline data
	output wire [`AluOpBus]		 id_alu_op,		 // ALU operation
	output wire [`WordDataBus]	 id_alu_in_0,	 // ALU input 0
	output wire [`WordDataBus]	 id_alu_in_1,	 // ALU input 1
	output wire					 id_br_flag,	 // Branch flag
	output wire [`MemOpBus]		 id_mem_op,		 // Memory opeartion
	output wire [`WordDataBus]	 id_mem_wr_data, // Data to write to memory
	output wire [`CtrlOpBus]	 id_ctrl_op,	 // Control operation
	output wire [`RegAddrBus]	 id_dst_addr,	 // GPR write address
	output wire					 id_gpr_we_,	 // GPR write enable
	output wire [`IsaExpBus]	 id_exp_code	 // Exception code
    );
    
    wire  [`AluOpBus]			 alu_op;		 // ALU operation
	wire  [`WordDataBus]		 alu_in_0;		 // ALU input 0
	wire  [`WordDataBus]		 alu_in_1;		 // ALU input 1
	wire						 br_flag;		 // Branch flag
	wire  [`MemOpBus]			 mem_op;		 // Memory operation
	wire  [`WordDataBus]		 mem_wr_data;	 // Data to write to memory
	wire  [`CtrlOpBus]			 ctrl_op;		 // Control operation
	wire  [`RegAddrBus]			 dst_addr;		 // GPR write address
	wire						 gpr_we_;		 // GPR write enable
	wire  [`IsaExpBus]			 exp_code;		 // Exception code
	
	/********** Decoder **********/
	decoder decoder (
		/********** IF/ID pipeline register **********/
		.if_pc			(if_pc),		  // Program counter
		.if_insn		(if_insn),		  // Instruction
		.if_en			(if_en),		  // Enable pipeline data
		/********** GPR interface **********/
		.gpr_rd_data_0	(gpr_rd_data_0),  // Read data 0
		.gpr_rd_data_1	(gpr_rd_data_1),  // Read data 1
		.gpr_rd_addr_0	(gpr_rd_addr_0),  // Read address 0
		.gpr_rd_addr_1	(gpr_rd_addr_1),  // Read address 1
		/********** Forwarding **********/
		// Forwarding form ID stage
		.id_en			(id_en),		  
		.id_dst_addr	(id_dst_addr),	  
		.id_gpr_we_		(id_gpr_we_),	  
		.id_mem_op		(id_mem_op),	 
		// Forwarding form EX stage
		.ex_en			(ex_en),		  
		.ex_fwd_data	(ex_fwd_data),	  
		.ex_dst_addr	(ex_dst_addr),	  
		.ex_gpr_we_		(ex_gpr_we_),	  
		// Forwarding form MEM stage
		.mem_fwd_data	(mem_fwd_data),	  
		/********** Control register interface **********/
		.exe_mode		(exe_mode),		  
		.creg_rd_data	(creg_rd_data),	  
		.creg_rd_addr	(creg_rd_addr),	  
		/********** Decode signal **********/
		.alu_op			(alu_op),		  
		.alu_in_0		(alu_in_0),		 
		.alu_in_1		(alu_in_1),		  
		.br_addr		(br_addr),		
		.br_taken		(br_taken),		 
		.br_flag		(br_flag),		 
		.mem_op			(mem_op),		  
		.mem_wr_data	(mem_wr_data),	 
		.ctrl_op		(ctrl_op),		 
		.dst_addr		(dst_addr),		  
		.gpr_we_		(gpr_we_),		
		.exp_code		(exp_code),		 
		.ld_hazard		(ld_hazard)		 
	);

	/********** Pipeline register **********/
	id_reg id_reg (
		/********** Clock & Reset **********/
		.clk			(clk),			 
		.reset			(reset),		  
		/********** Decode result **********/
		.alu_op			(alu_op),		  
		.alu_in_0		(alu_in_0),		 
		.alu_in_1		(alu_in_1),		  
		.br_flag		(br_flag),		  
		.mem_op			(mem_op),		  
		.mem_wr_data	(mem_wr_data),	
		.ctrl_op		(ctrl_op),		
		.dst_addr		(dst_addr),		  
		.gpr_we_		(gpr_we_),		  
		.exp_code		(exp_code),		  
		/********** Pipeline control signal **********/
		.stall			(stall),		
		.flush			(flush),		  
		/********** IF/ID pipeline register **********/
		.if_pc			(if_pc),		 
		.if_en			(if_en),		 
		/********** ID/EX pipeline register **********/
		.id_pc			(id_pc),		  
		.id_en			(id_en),		  
		.id_alu_op		(id_alu_op),	  
		.id_alu_in_0	(id_alu_in_0),	  
		.id_alu_in_1	(id_alu_in_1),	  
		.id_br_flag		(id_br_flag),	  
		.id_mem_op		(id_mem_op),	  
		.id_mem_wr_data (id_mem_wr_data),
		.id_ctrl_op		(id_ctrl_op),	 
		.id_dst_addr	(id_dst_addr),	  
		.id_gpr_we_		(id_gpr_we_),	  
		.id_exp_code	(id_exp_code)	 
	);

	
endmodule

4.gpr寄存器

之前的实验已经构建过此模块,这边用于测试时,实现将要执行数据的取出。
模块指向下图寄存器堆,主要连接端口是指令解码器中gpr_rd_addr_0、gpr_rd_addr_1、gpr_rd_data_0、gpr_rd_data_1
在这里插入图片描述

代码如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/01/24 18:08:00
// Design Name: 
// Module Name: gpr
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: General purpose register (GPR)
// 通用寄存器,两个读取端口,一个写入端口
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"

/********** Local header **********/
`include "cpu.vh"


module gpr(
     //时钟和复位
    input wire clk,
    input wire reset,
    /********** 读端口0 **********/
	input  wire [`RegAddrBus]  rd_addr_0,		   // Read address 位宽5
	output wire [`WordDataBus] rd_data_0,		   // Read data  位宽32
	/********** 读端口1 **********/
	input  wire [`RegAddrBus]  rd_addr_1,		   // Read address 位宽5
	output wire [`WordDataBus] rd_data_1,		   // Read data 位宽32
	/********** 写端口 **********/
	input  wire				   we_,				   // Write enable 位宽1
	input  wire [`RegAddrBus]  wr_addr,			   // Write address 位宽5
	input  wire [`WordDataBus] wr_data			   // Write data  位宽32

    );
    /********** Internal signal **********/
	reg [`WordDataBus]		   gpr [`REG_NUM-1:0]; // Register array 32*32
	integer					   i;              //初始化用迭代器,位宽32
	
	//读取端口0
	assign rd_data_0 =((we_==`ENABLE)&&(wr_addr==rd_addr_0))?
	                   wr_data:gpr[rd_addr_0];
     //读取端口1
     assign rd_data_1 =((we_==`ENABLE)&&(wr_addr==rd_addr_1))?
	                   wr_data:gpr[rd_addr_1]; 
	                   
   //异步复位
    always @(posedge clk or `RESET_EDGE reset)
    begin
    if(reset==`RESET_ENABLE)
        begin
        for (i=0;i<`REG_NUM;i=i+1)
        //`define REG_NUM				 32
            begin
            //`define WORD_DATA_W			32
                gpr[i] <= #1 `WORD_DATA_W'h0;
            end
            
        end
        else
            begin
                if(we_==`ENABLE_)
                    begin
                    gpr[wr_addr]<= #1 wr_data;
                    $display("写入gpr");
                    $display("gpr[%b]=%b",wr_addr,wr_data);
                    end
            end 
    end    
endmodule

5.测试模块(testbench)

测试思路:
在从IF/ID寄存器中拿到对应的指令,对指令进行处理,实现译码操作。
这边指令使用ADDSR寄存器间的有符号运算进行测试
将gpr【0】作为 alu0(即ra)
将gpr【1】作为 alu1(即rb)
将gpr【2】作为 dst_addr(即rc)
在这里插入图片描述

1.先将gpr中对应的位置写入数据
2.输入IF/ID寄存器的if_insn 指令
3.运算数据地址指向gpr中,gpr将发送对应数据
4.得到的数据发送到decoder中,进行解码操作
5.解码结果将放入ID/EX寄存器中,进行输出。
代码如下:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2022/02/09 11:18:15
// Design Name: 
// Module Name: id_test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
/********** Global header **********/
`include "nettype.vh"
`include "global_config.vh"
`include "stddef.vh"

/********** Local header **********/
`include "isa.vh"
`include "cpu.vh"

module id_test(

    );
    //端口定义
     /********** Clock & Reset **********/
    reg  clk;
    reg  reset;
    /********** GPR interface **********/
	wire   [`WordDataBus]	 gpr_rd_data_0;	 // Read data 0
	wire   [`WordDataBus]	 gpr_rd_data_1;	 // Read data 1
	wire  [`RegAddrBus]	 gpr_rd_addr_0;	 // Read Address 0
	wire  [`RegAddrBus]	 gpr_rd_addr_1;	 // Read Address 1
    reg				   we_;				   // Write enable 位宽1
	reg [`RegAddrBus]  wr_addr;			   // Write address 位宽5
	reg [`WordDataBus] wr_data;			   // Write data  位宽32
    /********** Forwarding **********/
	// Forwarding from EX stage
	reg  					 ex_en;			// Enable pipeline data
	reg   [`WordDataBus]	 ex_fwd_data;	 // Forwarding data
	reg   [`RegAddrBus]	 ex_dst_addr;	 // Write address
	reg  					 ex_gpr_we_;	 // Write enable
    // Forwarding from MEM stage
	reg   [`WordDataBus]	 mem_fwd_data;	 // Forwarding
	/********** Control register interface **********/
	reg   [`CpuExeModeBus] exe_mode;		 // Execution mode
	reg   [`WordDataBus]	 creg_rd_data;	 // Read data
	wire  [`RegAddrBus]	 creg_rd_addr;	 // Read address
	/********** Pipeline control signal **********/
	reg  					 stall;			 
	reg  					 flush;			 
	wire  [`WordAddrBus]	 br_addr;		 // Branch address
	wire 					 br_taken;		 // Branch taken
	wire 					 ld_hazard;		 // Load hazard
    
    /********** IF/ID pipeline register **********/
	reg   [`WordAddrBus]	 if_pc;			 // Program counter
	reg   [`WordDataBus]	 if_insn;		 // Instruction
	reg  					 if_en;			 // Enable pipeline data
	/********** ID/EX pipeline register **********/
	wire  [`WordAddrBus]	 id_pc;			 // Program counter
	wire 					 id_en;			 // Enable pipeline data
	wire  [`AluOpBus]		 id_alu_op;		 // ALU operation
	wire  [`WordDataBus]	 id_alu_in_0;	 // ALU reg 0
	wire  [`WordDataBus]	 id_alu_in_1;	 // ALU reg 1
	wire 					 id_br_flag;	 // Branch flag
	wire  [`MemOpBus]		 id_mem_op;		 // Memory opeartion
	wire  [`WordDataBus]	 id_mem_wr_data; // Data to write to memory
	wire  [`CtrlOpBus]	 id_ctrl_op;	 // Control operation
	wire  [`RegAddrBus]	 id_dst_addr;	 // GPR write address
	wire 					 id_gpr_we_;	 // GPR write enable
	wire  [`IsaExpBus]	 id_exp_code;	 // Exception code
	
    wire  [`AluOpBus]			 alu_op;		 // ALU operation
	wire  [`WordDataBus]		 alu_in_0;		 // ALU input 0
	wire  [`WordDataBus]		 alu_in_1;		 // ALU input 1
	wire						 br_flag;		 // Branch flag
	wire  [`MemOpBus]			 mem_op;		 // Memory operation
	wire  [`WordDataBus]		 mem_wr_data;	 // Data to write to memory
	wire  [`CtrlOpBus]			 ctrl_op;		 // Control operation
	wire  [`RegAddrBus]			 dst_addr;		 // GPR write address
	wire						 gpr_we_;		 // GPR write enable
	wire  [`IsaExpBus]			 exp_code;		 // Exception code
	
    integer i;
    parameter STEP=100;
    
    always#(STEP/2)begin
    clk<=~clk;
    end
    
    //实例化
	/********** Decoder **********/
	decoder decoder (
		/********** IF/ID pipeline register **********/
		.if_pc			(if_pc),		  // Program counter
		.if_insn		(if_insn),		  // Instruction
		.if_en			(if_en),		  // Enable pipeline data
		/********** GPR interface **********/
		.gpr_rd_data_0	(gpr_rd_data_0),  // Read data 0
		.gpr_rd_data_1	(gpr_rd_data_1),  // Read data 1
		.gpr_rd_addr_0	(gpr_rd_addr_0),  // Read address 0
		.gpr_rd_addr_1	(gpr_rd_addr_1),  // Read address 1
		/********** Forwarding **********/
		// Forwarding form ID stage
		.id_en			(id_en),		  
		.id_dst_addr	(id_dst_addr),	  
		.id_gpr_we_		(id_gpr_we_),	  
		.id_mem_op		(id_mem_op),	 
		// Forwarding form EX stage
		.ex_en			(ex_en),		  
		.ex_fwd_data	(ex_fwd_data),	  
		.ex_dst_addr	(ex_dst_addr),	  
		.ex_gpr_we_		(ex_gpr_we_),	  
		// Forwarding form MEM stage
		.mem_fwd_data	(mem_fwd_data),	  
		/********** Control register interface **********/
		.exe_mode		(exe_mode),		  
		.creg_rd_data	(creg_rd_data),	  
		.creg_rd_addr	(creg_rd_addr),	  
		/********** Decode signal **********/
		.alu_op			(alu_op),		  
		.alu_in_0		(alu_in_0),		 
		.alu_in_1		(alu_in_1),		  
		.br_addr		(br_addr),		
		.br_taken		(br_taken),		 
		.br_flag		(br_flag),		 
		.mem_op			(mem_op),		  
		.mem_wr_data	(mem_wr_data),	 
		.ctrl_op		(ctrl_op),		 
		.dst_addr		(dst_addr),		  
		.gpr_we_		(gpr_we_),		
		.exp_code		(exp_code),		 
		.ld_hazard		(ld_hazard)		 
	);

	/********** Pipeline register **********/
	id_reg id_reg (
		/********** Clock & Reset **********/
		.clk			(clk),			 
		.reset			(reset),		  
		/********** Decode result **********/
		.alu_op			(alu_op),		  
		.alu_in_0		(alu_in_0),		 
		.alu_in_1		(alu_in_1),		  
		.br_flag		(br_flag),		  
		.mem_op			(mem_op),		  
		.mem_wr_data	(mem_wr_data),	
		.ctrl_op		(ctrl_op),		
		.dst_addr		(dst_addr),		  
		.gpr_we_		(gpr_we_),		  
		.exp_code		(exp_code),		  
		/********** Pipeline control signal **********/
		.stall			(stall),		
		.flush			(flush),		  
		/********** IF/ID pipeline register **********/
		.if_pc			(if_pc),		 
		.if_en			(if_en),		 
		/********** ID/EX pipeline register **********/
		.id_pc			(id_pc),		  
		.id_en			(id_en),		  
		.id_alu_op		(id_alu_op),	  
		.id_alu_in_0	(id_alu_in_0),	  
		.id_alu_in_1	(id_alu_in_1),	  
		.id_br_flag		(id_br_flag),	  
		.id_mem_op		(id_mem_op),	  
		.id_mem_wr_data (id_mem_wr_data),
		.id_ctrl_op		(id_ctrl_op),	 
		.id_dst_addr	(id_dst_addr),	  
		.id_gpr_we_		(id_gpr_we_),	  
		.id_exp_code	(id_exp_code)	 
	);
	/*****gpr实例化***************/
	gpr gpr(
	   .clk(clk),
	   .reset(reset),
	   .rd_addr_0(gpr_rd_addr_0),
	    .rd_addr_1(gpr_rd_addr_1),
	    .rd_data_0(gpr_rd_data_0),
	    .rd_data_1(gpr_rd_data_1),
	    .we_(we_),
	    .wr_addr( wr_addr),
	    .wr_data( wr_data)
	);

    //测试
    assign id_en=`ENABLE_;
    
	initial begin
    #10 begin
    clk<=1;
    reset<=`RESET_ENABLE;
    end
    #(STEP*3/4)
    #STEP begin
    reset<=`RESET_DISABLE;
     #STEP
     we_<=`ENABLE_;
     wr_addr<=5'b00000;
     wr_data<=32'd10;
      #STEP
     we_<=`ENABLE_;
     wr_addr<=5'b00001;
     wr_data<=32'd20;
     #STEP
      we_<=`DISABLE_;
     if_en<=`ENABLE;
     if_insn<={{`ISA_OP_ADDSR},{5'b00000},{5'b00001},{5'b00010},{11{1'b0}}};
      #STEP
       stall <= `DISABLE;
        end
    #STEP
    $finish;
    
  end
	
endmodule

测试结果:
1.数据10写入gpr【0】
在这里插入图片描述
在这里插入图片描述
2.数据20写入gpr【1】
在这里插入图片描述
在这里插入图片描述
3.输入if指令if_insn<={{`ISA_OP_ADDSR},{5’b00000},{5’b00001},{5’b00010},{11{1’b0}}};
进行解码:
指令为ADDSR,
ra地址为0,对应gpr【0】。
rb地址为1,对应gpr【1】。
rc地址为2.对应gpr【2】。
将ra数据加上rb数据,结果存入rc中
这边定义了alu中指令编号为4(即0100):

`define ALU_OP_ADDS			 4'h4 // Signed ADD

在这里插入图片描述
4.将对应的解码结果输入到ID/EX寄存器中,并且output
仿真结束。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值