0
点赞
收藏
分享

微信扫一扫

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


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

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

前言

编写于
2022/11/22

VIP发布于
2022/11/22

实验于
2022/11/24

发布于
2022/11/24

以下内容源自计算机组成原理实验
仅供学习交流使用

推荐

​​Modelsim10.7中文注释乱码问题​​

实验三 ORI指令设计实验

一、实验目的

  1. 理解MIPS处理器指令格式及功能。
  2. 掌握ori指令格式与功能。
  3. 掌握ModelSim和ISE\Vivado工具软件。
  4. 掌握基本的测试代码编写和FPGA开发板使用方法。

二、实验环境

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

三、实验原理

MIPS是一款作为上世纪80年代的推出处理器,在美国与我国许多著名高校都作为教学研究的处理器。本次实验以32位MIPS为例,通过设计基本的MIPS指令集,从而掌握现代处理器的设计原理与方法。
MIPS处理器的指令格式分为R型、I型和J型。R型为寄存器型,即两个源操作数和目的操作数都是寄存器性。I型为操作数含有立即数。而J型特指转移类型指令,如图1所示。

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

图1 MIPS指令类型
如图2所示,本次实验及其后续实验挑选部分MIPS处理器指令进行实现。以ori指令为例说明,其中rs为源操作数寄存器,imm为立即数型源操作数,由于是逻辑运算,所以imm按无符号数(零)扩展为32位数,运算结果存入rt目的操作数寄存器。

实验三 ORI指令设计实验【计算机组成原理】_寄存器_02

图2 MIPS处理器基本指令格式和功能
如图3所示为按照单指令周期设计MIPS处理器内部结构。所有控制信号及字段均标注出来。另外,每条指令周期都包含2个clk,即PC模块用1个clk,Regfile和DataMem模块用1个clk,也可以说是由2个时钟构成的指令流水线。

实验三 ORI指令设计实验【计算机组成原理】_fpga开发_03

图3 单指令周期MIPS内部结构示意图

为了便于今后的扩展,将MIPS处理器在图3的基础上进行了分阶段设计,这样结构更清晰,也有利于流水线的设计。随着后续指令的不断添加,处理器内部结构设计也会进行相应的调整。

实验三 ORI指令设计实验【计算机组成原理】_fpga开发_04

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

四、实验任务

  1. 用Verilog HDL设计32位MIPS处理器ORI指令实现,参照图4的MIPS内部结构示意图,将设计的MIPS处理器改造为分阶段实现方案,注意每条指令周期平均只包含1个时钟周期。先编写基本实现代码,即能实现ORI指令的取指令和执行指令。
  2. 编写指令存储测试文件,设计SoC系统,并在Modelsim上仿真测试调试通过。

五、实验思考

1、在完成基本实验的基础上,如图4所示,将ANDI, XOI, ADDI,SUBI和LUI等指令添加进去,然后进行设计实现和验证结果。
参考资料:
[1]李亚民.计算机原理与设计:Verilog HDL版.北京:清华大学出版社.2011年.

附录

实验三 ORI指令设计实验【计算机组成原理】_fpga开发_05

实验三 ORI指令设计实验【计算机组成原理】_指令周期_06

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

`define Inst_ori 6'b001101

`define Nop 6'b000000
`define Or 6'b000001

IF

实验三 ORI指令设计实验【计算机组成原理】_操作数_07

`include "define.v";
//控制PC,程序计数器
module IF(
input wire clk,
input wire rst,
output reg ce,
output reg [31:0] pc
);
always@(*)
if(rst == `RstEnable)
ce = `RomDisable;
else
ce = `RomEnable;
always@(posedge clk)
if(ce == `RomDisable)
pc = `Zero;
else
pc = pc + 4;
endmodule

ID

实验三 ORI指令设计实验【计算机组成原理】_寄存器_08

`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;

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
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

实验三 ORI指令设计实验【计算机组成原理】_寄存器_09

`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;
default:
regcData = `Zero;
endcase
assign regcWrite = regcWrite_i;
assign regcAddr = regcAddr_i;
endmodule

RegFile

实验三 ORI指令设计实验【计算机组成原理】_寄存器_10

`include "define.v";
//为操作数取值模块
module RegFile(
input wire clk,
input wire rst,
input wire we,
input wire [4:0] waddr,
input wire [31:0] wdata,
input wire regaRead,
input wire regbRead,
input wire [4:0] regaAddr,
input wire [4:0] regbAddr,
output reg [31:0] regaData,
output reg [31:0] regbData
);
reg [31:0] reg32 [31 : 0];
always@(*)
if(rst == `RstEnable)
regaData = `Zero;
else if(regaAddr == `Zero)
regaData = `Zero;
else
regaData = reg32[regaAddr];
always@(*)
if(rst == `RstEnable)
regbData = `Zero;
else if(regbAddr == `Zero)
regbData = `Zero;
else
regbData = reg32[regbAddr];
always@(posedge clk)
if(rst == `RstDisable)
if((we == `Valid) && (waddr != `Zero))
reg32[waddr] = wdata;
else ;

endmodule

MIPS

实验三 ORI指令设计实验【计算机组成原理】_操作数_11

`include "define.v";
//MIPS封装
module MIPS(
input wire clk,
input wire rst,
input wire [31:0] instruction,
output wire romCe,
output wire [31:0] instAddr
);
wire [31:0] regaData_regFile, regbData_regFile;
wire [31:0] regaData_id, regbData_id;
wire [31:0] regcData_ex;
wire [5:0] op;
wire regaRead, regbRead;
wire [4:0] regaAddr, regbAddr;
wire regcWrite_id, regcWrite_ex;
wire [4:0] regcAddr_id, regcAddr_ex;
IF if0(
.clk(clk),
.rst(rst),
.ce(romCe),
.pc(instAddr)
);
ID id0(
.rst(rst),
.inst(instruction),
.regaData_i(regaData_regFile),
.regbData_i(regbData_regFile),
.op(op),
.regaData(regaData_id),
.regbData(regbData_id),
.regaRead(regaRead),
.regbRead(regbRead),
.regaAddr(regaAddr),
.regbAddr(regbAddr),
.regcWrite(regcWrite_id),
.regcAddr(regcAddr_id)
);

EX ex0(
.rst(rst),
.op(op),
.regaData(regaData_id),
.regbData(regbData_id),
.regcWrite_i(regcWrite_id),
.regcAddr_i(regcAddr_id),
.regcData(regcData_ex),
.regcWrite(regcWrite_ex),
.regcAddr(regcAddr_ex)
);
RegFile regfile0(
.clk(clk),
.rst(rst),
.we(regcWrite_ex),
.waddr(regcAddr_ex),
.wdata(regcData_ex),
.regaRead(regaRead),
.regbRead(regbRead),
.regaAddr(regaAddr),
.regbAddr(regbAddr),
.regaData(regaData_regFile),
.regbData(regbData_regFile)
);

endmodule

InstMem

实验三 ORI指令设计实验【计算机组成原理】_指令周期_12

//指令存储器
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;
instmem [1] = 32'h34020020;
instmem [2] = 32'h3403ff00;
instmem [3] = 32'h3404ffff;
end
endmodule

SoC

实验三 ORI指令设计实验【计算机组成原理】_fpga开发_13

//系统封装
module SoC(
input wire clk,
input wire rst
);
wire [31:0] instAddr;
wire [31:0] instruction;
wire romCe;
MIPS mips0(
.clk(clk),
.rst(rst),
.instruction(instruction),
.instAddr(instAddr),
.romCe(romCe)
);

InstRom instrom0(
.ce(romCe),
.addr(instAddr),
.data(instruction)
);
endmodule

soc_tb

`include "define.v";
//测试系统
module soc_tb;
reg clk;
reg rst;
initial
begin
clk = 0;
rst = `RstEnable;
#100
rst = `RstDisable;
#1000 $stop;
end
always #10 clk = ~ clk;
SoC soc0(
.clk(clk),
.rst(rst)
);
endmodule

结果

实验三 ORI指令设计实验【计算机组成原理】_指令周期_14

最后

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

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

开源:为爱发电

学习:为我而行


举报

相关推荐

0 条评论