实验四 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
这篇博客能写好的原因是:站在巨人的肩膀上
这篇博客要写好的目的是:做别人的肩膀