自己动手写CPU之第四阶段(2)

将陆续上传本人写的新书《自己动手写CPU》(尚未出版),今天是第12篇,我尽量每周四篇

书名又之前的《自己动手写处理器》改为《自己动手写CPU》

4.3 验证OpenMIPS实现效果4.3.1指令存储器ROM的实现

本节将验证我们的OpenMIPS是否实现正确,包含:流水线是否正确、ori指令是否实现正确。在验证之前,需要首先实现指令存储器,以便OpenMIPS从中读取指令。

指令存储器模块是只读的,其接口如图4-7所示,还是采用左边是输入接口,右边是输出接口的方式绘制,这样便于理解。接口含义如表4-12所示。

指令存储器ROM模块在文件inst_rom.v中实现,代码如下,可以在本书附带光盘的Code\Chapter4\目录下找到源文件。

module inst_rom(input wirece,input wire[`InstAddrBus]addr,output reg[`InstBus]inst);// 定义一个数组,大小是InstMemNum,元素宽度是InstBusreg[`InstBus] inst_mem[0:`InstMemNum-1];// 使用文件inst_rom.data初始化指令存储器initial $readmemh ( "inst_rom.data", inst_mem );// 当复位信号无效时,依据输入的地址,给出指令存储器ROM中对应的元素always @ (*) begin if (ce == `ChipDisable) begininst <= `ZeroWord; end else begininst <= inst_mem[addr[`InstMemNumLog2+1:2]]; endendendmodule

代码很好理解,有以下几点说明。

(1)在初始化指令存储器时,使用了initial过程语句。initial过程语句只执行一次,通常用于仿真模块中对激励向量的描述,或用于给变量赋初值,是面向模拟仿真的过程语句,通常不能被综合工具支持。所以如果要将本章实现的OpenMIPS处理器使用综合工具进行综合,那么需要修改这里初始化指令存储器的方法。

(2)在初始化指令存储器时,使用了系统函数$readmemh,表示从inst_rom.data文件中读取数据以初始化inst_mem,而inst_mem正是之前定义的数组。inst_rom.data是一个文本文件,里面存储的是指令,其每行存储一条32位宽度的指令(使用十六进制表示),系统函数$readmemh会将inst_rom.data中的数据依次填写到inst_mem数组中。

(3)OpenMIPS是按照字节寻址的,而此处定义的指令存储器的每个地址是一个32bit的字,所以要将OpenMIPS给出的指令地址除以4再使用,比如:要读取地址0xC处的指令,那么实际就是对应ROM的inst_mem[3],如图4-8所示。

除以4也就是将指令地址右移2位,所以在读取的时候给出的地址是addr[`InstMemNumLog2+1:2],其中InstMemNumLog2是指令存储器的实际地址宽度,比如:如果inst_mem有1024个元素,那么InstMemNum等于1024,InstMemNumLog2等于10,表示实际地址宽度为10。

4.3.2 最小SOPC的实现

为了验证,需要建立一个SOPC,其中仅包含OpenMIPS、指令存储器ROM,所以是一个最小SOPC。OpenMIPS从指令存储器中读取指令,指令进入OpenMIPS开始执行。最小SOPC的结构如图4-9所示。

最小SOPC对应的模块是openmips_min_sopc,位于文件openmips_min_sopc.v中,读者可以在本书附带光盘的Code\Chapter4\目录下找到该文件,主要内容如下。在其中例化了处理器OpenMIPS、指令存储器ROM,并将两者按照图4-9的方式连接。

module openmips_min_sopc(inputwireclk,input wirerst);// 连接指令存储器 wire[`InstAddrBus] inst_addr; wire[`InstBus]inst;wirerom_ce;// 例化处理器OpenMIPS openmips openmips0(.clk(clk),.rst(rst),.rom_addr_o(inst_addr),.rom_data_i(inst),.rom_ce(rom_ce));// 例化指令存储器ROMinst_rom inst_rom0(.ce(rom_ce),.addr(inst_addr),.inst(inst));endmodule4.3.3 编写测试程序

我们需要写一段测试程序,并将其存储到指令存储器ROM,这样当上一节建立的最小SOPC开始运行的时候,就会从ROM中取出我们的程序,送入OpenMIPS处理器执行。由于目前的OpenMIPS只实现了一条ori指令,所以测试程序很简单,如下,对应本书附带光盘Code\Chapter4\TestAsm目录下的inst_rom.S文件。

ori $1,$0,0×1100# $1 = $0 | 0x1100 = 0x1100 ori $2,$0,0×0020# $2 = $0 | 0x0020 = 0x0020 ori $3,$0,0xff00# $3 = $0 | 0xff00 = 0xff00 ori $4,$0,0xffff# $4 = $0 | 0xffff = 0xffff

共有4条指令,都是ori指令。

第1条指令将0x1100进行零扩展后与寄存器$0进行逻辑“或”运算,结果保存在寄存器$1中。

第2条指令将0x0020进行零扩展后与寄存器$0进行逻辑“或”运算,结果保存在寄存器$2中。

第3条指令将0xff00进行零扩展后与寄存器$0进行逻辑“或”运算,结果保存在寄存器$3中。

第4条指令将0xffff进行零扩展后与寄存器$0进行逻辑“或”运算,,结果保存在寄存器$4中。

躲在某一时间想念一段时光的掌纹,

自己动手写CPU之第四阶段(2)

相关文章:

你感兴趣的文章:

标签云: