實驗四 OR指令設計實驗【計算機組成原理】
- 前言
- 推薦
- 實驗四 OR指令設計實驗
- 一、實驗目的
- 二、實驗環境
- 三、實驗原理
- 四、實驗任務
- 五、實驗思考
- 結果
- 附錄
- define
- ID
- EX
- InstMem
推薦
實驗三 ORI指令設計實驗【計算機組成原理】
實驗四 OR指令設計實驗
一、實驗目的
- 了解MIPS處理器指令格式及功能。
- 掌握addi, andi, xori, add, sub, and, or, xor, sll, srl, sra, jr指令格式與功能。
- 掌握ModelSim和ISE\Vivado工具軟體。
- 掌握基本的測試代碼編寫和FPGA開發闆使用方法。
二、實驗環境
- 裝有ModelSim和ISE\Vivado的計算機。
- Sword\Basys3\EGo1實驗系統。
三、實驗原理
MIPS 32位處理器的指令格式分為R型、I型和J型。R型為寄存器型,即兩個源操作數和目的操作數都是寄存器性。I型為操作數含有立即數。而J型特指轉移類型指令,如圖1所示。
圖1 MIPS指令類型
如圖2所示,本次實驗及其後續實驗挑選部分MIPS處理器指令進行實作。需要實作add, sub, and, or, xor, sll, srl, sra指令功能。具體指令格式如下表所示。
可參考圖3的結構框圖,按照指令的功能,設計MIPS處理器内部實作。具體指令的功能參見參考資料1(李亞民. 計算機原理與設計:Verilog HDL版)。在設計時注意指令的時序關系,既單指令周期CPU時序。
圖2 MIPS處理器基本指令格式和功能
圖3 單指令周期MIPS分階段結構示意圖
如圖3所示為按照單指令周期設計MIPS處理器内部結構。所有控制信号及字段均标注出來。另外,每條指令周期都包含2個clk,即PC子產品用1個clk,Regfile和DataMem子產品用1個clk,也可以說是由2個時鐘構成的指令流水線。為了便于今後的擴充,将MIPS處理器進行了分階段設計,這樣結構更清晰,也有利于流水線的設計。随着後續指令的不斷添加,處理器内部結構設計也會進行相應的調整,但應保證時序關系不變。
四、實驗任務
- 用Verilog HDL設計32位MIPS處理器R和I型指令實作,參照圖1的MIPS内部結構示意圖,參考基本實作代碼,在實作ori指令的基礎上,實作or指令功能,在Modelsim上仿真測試。
-
如圖3所示,将設計的MIPS處理器設計為單指令周期CPU,,注意每條指令周期平均隻包含1個時鐘周期。
3.編寫指令存儲測試檔案,在Modelsim上調試通過。
五、實驗思考
在完成基本實驗的基礎上,嘗試修改處理器内部結構設計,在圖3的基礎上,考慮and, xor, add, sub, sll, srl, sra等指令的實作。
參考資料:
[1] 李亞民. 計算機原理與設計:Verilog HDL版.北京:清華大學出版社.2011年.
結果
附錄
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
這篇部落格能寫好的原因是:站在巨人的肩膀上
這篇部落格要寫好的目的是:做别人的肩膀