4.3 验证OpenMIPS实现效果
4.3.1 指令存储器ROM的实现
本节我们验证OpenMIPS是否实现正确,包含:流水线是否正确、ori指令实现是否正确。指令存储器ROM是只读的,接口如图所示:
`include "defines.v"
module inst_rom(
// input wire clk,
input wire ce,
input wire[`InstAddrBus] addr,
output reg[`InstBus] inst
);
reg[`InstBus] inst_mem[0:`InstMemNum-1];
initial $readmemh ( "inst_rom.data", inst_mem );
always @ (*) begin
if (ce == `ChipDisable) begin
inst <= `ZeroWord;
end else begin
inst <= inst_mem[addr[`InstMemNumLog2+1:2]];
end
end
endmodule
4.3.2 最小SOPC的实现
为了验证,需要建立一个SOPC,其中仅OpenMIPS、指令存储器ROM,所以是一个最小SOPC。Openmips从指令存储器中读取指令,指令进入OpenMIPS开始执行。最小SOPC的结构如图所示:
`include "defines.v"
module openmips_min_sopc(
input wire clk,
input wire rst
);
wire[`InstAddrBus] inst_addr;
wire[`InstBus] inst;
wire rom_ce;
openmips openmips0(
.clk(clk),
.rst(rst),
.rom_addr_o(inst_addr),
.rom_data_i(inst),
.rom_ce_o(rom_ce)
);
inst_rom inst_rom0(
.addr(inst_addr),
.inst(inst),
.ce(rom_ce)
);
endmodule
4.3.3编写测试程序
我们写一段测试程序,并将其存储到指令存储器ROM,这样当最小SOPC开始运行时,会从rom中取出我们的程序,送入OpenMIPS处理器中执行。
测试程序共有四条指令,都是ori指令
.org 0x0
.global _start
.set noat
_start:
ori $1,$0,0x1100 # $1 = $0 | 0x1100 = 0x1100
ori $2,$0,0x0020 # $2 = $0 | 0x0020 = 0x0020
ori $3,$0,0xff00 # $3 = $0 | 0xff00 = 0xff00
ori $4,$0,0xffff # $4 = $0 | 0xffff = 0xffff
- 第一条指令将0x1100进行零扩展后与寄存器$0进行逻辑“或”运算,结果保存在寄存器$1中
- 第二条指令将0x0020进行零扩展后与寄存器$0进行逻辑“或”运算,结果保存在寄存器$2中
- 第一条指令将0xff00进行零扩展后与寄存器$0进行逻辑“或”运算,结果保存在寄存器$3中
- 第一条指令将0xffff进行零扩展后与寄存器$0进行逻辑“或”运算,结果保存在寄存器$4中
零扩展的定义:零扩展非常简单,只需要用零来填充大位数操作数的高端各个字节即可。
具体可参考文章:https://blog.csdn.net/yjk13703623757/article/details/78084491
4.3.4建立Test Bench文件
给出最小SOPC运行所需要的时钟信号、复位信号。代码如下:
`include "defines.v"
`timescale 1ns/1ps
module openmips_min_sopc_tb();
reg CLOCK_50;
reg rst;
initial begin
CLOCK_50 = 1'b0;
forever #10 CLOCK_50 = ~CLOCK_50;
end
initial begin
rst = `RstEnable;
#195 rst= `RstDisable;
#1000 $stop;
end
openmips_min_sopc openmips_min_sopc0(
.clk(CLOCK_50),
.rst(rst)
);
endmodule
4.3.5 检测实现效果
这里书的部分我看不懂,我个人使用Vivado来运行和测试,会出现一个电路图。我将书上部分截图出来,自己做测试的结果也是同样的电路图