天天看点

实验四 OR指令设计实验【计算机组成原理】

实验四 OR指令设计实验【计算机组成原理】

  • ​​前言​​
  • ​​推荐​​
  • ​​实验四 OR指令设计实验​​
  • ​​一、实验目的​​
  • ​​二、实验环境​​
  • ​​三、实验原理​​
  • ​​四、实验任务​​
  • ​​五、实验思考​​
  • ​​结果​​
  • ​​附录​​
  • ​​define​​
  • ​​ID​​
  • ​​EX​​
  • ​​InstMem​​

推荐

​​实验三 ORI指令设计实验【计算机组成原理】​​

实验四 OR指令设计实验

一、实验目的

  1. 理解MIPS处理器指令格式及功能。
  2. 掌握addi, andi, xori, add, sub, and, or, xor, sll, srl, sra, jr指令格式与功能。
  3. 掌握ModelSim和ISE\Vivado工具软件。
  4. 掌握基本的测试代码编写和FPGA开发板使用方法。

二、实验环境

  1. 装有ModelSim和ISE\Vivado的计算机。
  2. Sword\Basys3\EGo1实验系统。

三、实验原理

MIPS 32位处理器的指令格式分为R型、I型和J型。R型为寄存器型,即两个源操作数和目的操作数都是寄存器性。I型为操作数含有立即数。而J型特指转移类型指令,如图1所示。

实验四 OR指令设计实验【计算机组成原理】

图1 MIPS指令类型

如图2所示,本次实验及其后续实验挑选部分MIPS处理器指令进行实现。需要实现add, sub, and, or, xor, sll, srl, sra指令功能。具体指令格式如下表所示。

可参考图3的结构框图,按照指令的功能,设计MIPS处理器内部实现。具体指令的功能参见参考资料1(李亚民. 计算机原理与设计:Verilog HDL版)。在设计时注意指令的时序关系,既单指令周期CPU时序。

实验四 OR指令设计实验【计算机组成原理】

图2 MIPS处理器基本指令格式和功能

实验四 OR指令设计实验【计算机组成原理】

图3 单指令周期MIPS分阶段结构示意图

如图3所示为按照单指令周期设计MIPS处理器内部结构。所有控制信号及字段均标注出来。另外,每条指令周期都包含2个clk,即PC模块用1个clk,Regfile和DataMem模块用1个clk,也可以说是由2个时钟构成的指令流水线。为了便于今后的扩展,将MIPS处理器进行了分阶段设计,这样结构更清晰,也有利于流水线的设计。随着后续指令的不断添加,处理器内部结构设计也会进行相应的调整,但应保证时序关系不变。

四、实验任务

  1. 用Verilog HDL设计32位MIPS处理器R和I型指令实现,参照图1的MIPS内部结构示意图,参考基本实现代码,在实现ori指令的基础上,实现or指令功能,在Modelsim上仿真测试。
  2. 如图3所示,将设计的MIPS处理器设计为单指令周期CPU,,注意每条指令周期平均只包含1个时钟周期。

    3.编写指令存储测试文件,在Modelsim上调试通过。

五、实验思考

在完成基本实验的基础上,尝试修改处理器内部结构设计,在图3的基础上,考虑and, xor, add, sub, sll, srl, sra等指令的实现。

参考资料:

[1] 李亚民. 计算机原理与设计:Verilog HDL版.北京:清华大学出版社.2011年.

结果

实验四 OR指令设计实验【计算机组成原理】

附录

define

//宏定义文件
`define RstEnable 1'b1
`define RstDisable 1'b0
`define RomEnable 1'b1
`define RomDisable 1'b0
`define Zero 0
`define Valid 1'b1
`define Invalid 1'b0

//指令外部编码
//I型编码
`define Inst_ori 6'b001101
`define Inst_lui 6'b100000

//R型编码
`define Inst_reg 6'b000000

`define Inst_add 6'b100000
`define Inst_sub 6'b100010
`define Inst_and 6'b100100
`define Inst_or  6'b100101
`define Inst_xor 6'b100110

`define Inst_sll 6'b000000
`define Inst_srl 6'b000010
`define Inst_sra 6'b000011

//内部供EX的编码
`define Nop 6'b000000
`define Or  6'b000001
`define And 6'b000010
`define Xor 6'b000011
`define Add 6'b000100
`define Sub 6'b000101
`define Sll 6'b000110
`define Srl 6'b000111
`define Sra 6'b001000      

ID

`include "define.v";
//为操作数做准备
module  ID (
    input wire rst,    
    input wire [31:0] inst,
    input wire [31:0] regaData_i,
    input wire [31:0] regbData_i,
    output reg [5:0] op,    
    output reg [31:0] regaData,
    output reg [31:0] regbData,
    output reg regaRead,
    output reg regbRead,
    output reg regcWrite,
    output reg [4:0] regaAddr,
    output reg [4:0] regbAddr,    
    output reg [4:0] regcAddr
);
    //操作指令
    wire [5:0] inst_op = inst[31:26];   
    //扩展的立即数 
    reg [31:0] imm;
   //用于R型指令
    wire[5:0] func = inst[5:0]; 

    always@(*)
        if(rst == `RstEnable)
          begin
            op = `Nop;            
            regaRead = `Invalid;
            regbRead = `Invalid;
            regcWrite = `Invalid;
            regaAddr = `Zero;
            regbAddr = `Zero;
            regcAddr = `Zero;
            imm = `Zero;
          end
      else  
            case(inst_op)
               `Inst_ori:
                  begin
                    op = `Or;                    
                    regaRead = `Valid;
                    regbRead = `Invalid;
                    regcWrite = `Valid;
                    regaAddr = inst[25:21];
                    regbAddr = `Zero;
                    regcAddr = inst[20:16];
                    imm = {16'h0, inst[15:0]};
                  end
                  `Inst_reg:
                  case(func)
                        `Inst_add:
                                 begin
                                    op = `Add;
                                     regaRead = `Valid;
                                     regbRead = `Valid;
                                     regcWrite = `Valid;
                                     regaAddr = inst[25:21];
                                     regbAddr = inst[20:16];
                                 regcAddr = inst[15:11];
                                     imm = `Zero;
                                  end

                     `Inst_or:
                             begin
                                 op = `Or;
                                 regaRead = `Valid;
                                 regbRead = `Valid;
                                 regcWrite = `Valid;
                                 regaAddr = inst[25:21];
                                 regbAddr = inst[20:16];
                                 regcAddr = inst[15:11];
                                 imm = `Zero;
                             end
                     default:
                             begin
                                 op = `Nop;
                                 regaRead = `Invalid;
                                 regbRead = `Invalid;
                                 regcWrite = `Invalid;
                                 regaAddr = `Zero;
                                 regbAddr = `Zero;
                               regcAddr = `Zero;
                                 imm = `Zero;
                                 end
                        endcase

         default:
                  begin
                    op = `Nop;                    
                    regaRead = `Invalid;
                    regbRead = `Invalid;
                    regcWrite = `Invalid;
                    regaAddr = `Zero;
                    regbAddr = `Zero;
                    regcAddr = `Zero;
                    imm = `Zero;
                  end
            endcase 



   //二选一 regaData= regaData_i : imm
   always@(*)
      if(rst == `RstEnable)
          regaData = `Zero;
      else if(regaRead == `Valid)
          regaData = regaData_i;
      else  
          regaData = imm;

   //二选一 regbData= regbData_i : imm
    always@(*)
      if(rst == `RstEnable)
          regbData = `Zero;      
      else if(regbRead == `Valid)
          regbData = regbData_i;
      else
          regbData = imm; 
endmodule      

EX

`include "define.v";
//执行指令模块
module EX (
        input wire rst,
        input wire [5:0] op,        
        input wire [31:0] regaData,
        input wire [31:0] regbData,
        input wire regcWrite_i,
        input wire [4:0] regcAddr_i,
        output reg [31:0] regcData,
        output wire regcWrite,
        output wire [4:0] regcAddr
    );   
    always@(*)
        if(rst == `RstEnable)
              regcData = `Zero;
        else
            case(op)
                `Or:
                    regcData = regaData | regbData;
                `Add:
                    regcData = regaData + regbData;
                `Sub:
                    regcData = regaData - regbData;
                `And:
                    regcData = regaData & regbData;
      
                `Sll:
                    regcData = regbData << regaData;
                `Srl:
                    regcData = regbData >> regaData;
              default:
                  regcData = `Zero;
  
            endcase    
            
    assign regcWrite = regcWrite_i;
    assign regcAddr = regcAddr_i;
endmodule      

InstMem

`include "define.v";
//指令存储器
module InstMem(
    input wire ce,
    input wire [31:0] addr,
    output reg [31:0] data
);
    reg [31:0] instmem [1023 : 0];    
    always@(*)      
        if(ce == `RomDisable)
          data = `Zero;
        else
          data = instmem[addr[11 : 2]];   
    initial
      begin
        instmem [0] = 32'h34011100;//ori,R1,1100
        instmem [1] = 32'h34020020;//ori,R2,0020
        instmem [2] = 32'h3403ff00;//ori,R3,ff00
        instmem [3] = 32'h3404ffff;//ori,R4,ffff
        instmem [4] = 32'b000000_00001_00010_00101_00000_100000;//add,R5,R1,R2
        instmem [5] = 32'b000000_00001_00010_00110_00000_100101;//or,R6,R1,R2
      end
endmodule      

最后

2022/11/29 19:43

这篇博客能写好的原因是:站在巨人的肩膀上

这篇博客要写好的目的是:做别人的肩膀

继续阅读