ORI指令实现代码

4.2.3一些宏定义
在正式进行流水线结构实现之前,需要给出一些宏定义,因为在OpenMIPs实现过程中为提高代码可读性和易懂性,使用较多的宏。

我个人对宏定义的一些小理解:就是把一些通用的定义单独放在一个文件里,这样不仅美观,而且需要更改的时候也方便,写其他代码时可以参照宏定义,便于我们的编程,也便于集体合作。

以下为ori指令所需要进行的宏定义
`define RstEnable 1'b1          //复位信号有效
`define RstDisable 1'b0         //复位信号无效
`define ZeroWord 32'h00000000   //32位的数值0
`define WriteEnable 1'b1        //使能写
`define WriteDisable 1'b0       //禁止写
`define ReadEnable 1'b1         //使能读
`define ReadDisable 1'b0        //禁止读
`define AluOpBus 7:0            //译码阶段输出lauop_o的宽度
`define AluSelBus 2:0           //译码阶段输出alusel的宽度
`define InstValid 1'b0          //指令有效
`define InstInvalid 1'b1        //指令无效
`define True_v 1'b1                     //逻辑真
`define False_v 1'b0                    //逻辑假
`define ChipEnable 1'b1                 //芯片能使
`define ChipDisable 1'b0                //芯片禁止
//指令
`define EXE_ORI  6'b001101              //指令ori的指令码
`define EXE_NOP 6'b000000

//AluOp
`define EXE_ORI_OP  8'b01011010
`define EXE_NOP_OP  8'b00000000

//AluSel
`define EXE_RES_LOGIC 3'b001

//指令存储器inst_rom
`define InstAddrBus 31:0                   //ROM地址总线宽度
`define InstBus 31:0                       //ROM数据总线宽度
`define InstMemNum 131071                  //ROM实际大小为128KB
`define InstMemNumLog2 17                  //ROM实际使用的地址线宽度

//通用寄存器regfile
`define RegAddrBus 4:0                     //regfile模块的地址线宽度
`define RegBus 31:0                        //regfile模块的数据线宽度  
`define RegWidth 32                        //通用寄存器的宽度
`define DoubleRegWidth 64                  //两倍的通用寄存器的宽度
`define DoubleRegBus 63:0                  //两倍的通用寄存器的数据线宽度
`define RegNum 32                          //通用寄存器的数量
`define RegNumLog2 5                       //寻址通用寄存器使用的地址位数
`define NOPRegAddr 5'b00000

上述宏定义为MIPS指令集规定的,其中部分会与龙芯(企业有些差距,如果选择就业到时候可以更改)
4.2.4 取指阶段的实现
取指阶段取出指令存储器中的指令,同时,PC值递增,准备取下一条指令,包括PC、IF/ID两个模块。
  1. PC模块
    PC模块的作用是给出指令地址,其接口描述如表所示
    在这里插入图片描述
`include "defines.v"
module pc_reg(
    input wire                clk,
    input wire                rst,

    output reg[`InstAddrBus]  pc,
    output reg                ce
    );
    always @(posedge clk) begin
        if(ce == `ChipDisable) begin
            pc <= 32'h00000000;
        end else begin
            pc <= pc + 4'h4;
        end
    end

    always @(posedge clk) begin
        if(rst == `RstEnable) begin
            ce <= `ChipDisable;
        end else begin
            ce <= `ChipEnable;
        end
    end
endmodule

在这里插入图片描述

  1. IF/ID模块
    IF/ID模块的作用是暂时保存取指阶段取得的指令,以及对应的指令地址,并在下一个时钟传递到译码阶段,其接口为:
    在这里插入图片描述
`include "defines.v"

module if_id(

   input	wire										clk,
   input wire										rst,
   

   input wire[`InstAddrBus]			if_pc,
   input wire[`InstBus]          if_inst,
   output reg[`InstAddrBus]      id_pc,
   output reg[`InstBus]          id_inst  
   
);

   always @ (posedge clk) begin//时钟上升
   	if (rst == `RstEnable) begin//复位归0
   		id_pc <= `ZeroWord;
   		id_inst <= `ZeroWord;
     end else begin
   	  id_pc <= if_pc;//传递取指阶段的值
   	  id_inst <= if_inst;
   	end
   end

endmodule

IF/ID模块只是简单地将取指阶段的结果在每个时钟周期的上升沿传递到译码阶段。

4.2.5译码阶段的实现

对取到的指令进行译码:给出要进行的运算类型,以及参与运算的操作数。译码阶段包括Regfile、ID和ID/EX模块。

  • Regfile模块
    Regfile模块实现了32个32位通用整数寄存器,可以同时进行两个寄存器的读操作和一个寄存器的写操作,其接口如图所示
    在这里插入图片描述在这里插入图片描述
`include "defines.v"
module regfile(
      input wire                 clk,
      input wire                 rst,
      
      input wire                 we,
      input wire [`RegAddrBus]   waddr,
      input wire [`RegBus]       wdata,

      input wire                 re1,
      input wire [`RegAddrBus]   raddr1,
      output reg [`RegBus]       rdata1,

      input wire                 re2,
      input wire [`RegAddrBus]   raddr2,
      output reg [`RegBus]       rdata2
    );

    reg[`RegBus] regs[0:`RegNum-1];

    always @(posedge clk) begin
        if(rst == `RstDisable) begin
            if((we == `WriteEnable)&&(waddr != `RegNumLog2'h0)) begin
                 regs[waddr] <= wdata;
            end
        end
    end
    always @
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值