天天看點

實驗四 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

這篇部落格能寫好的原因是:站在巨人的肩膀上

這篇部落格要寫好的目的是:做别人的肩膀

繼續閱讀