北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计

北航计算机学院-计算机组成原理课程设计-2021秋

PreProject-MIPS

测试程序设计


本系列所有博客,知识讲解、习题以及答案均由北航计算机学院计算机组成原理课程组创作,解析部分由笔者创作,如有侵权联系删除。


从本节开始,课程组给出的教程中增添了很多视频讲解。为了避免侵权,本系列博客将不会搬运课程组的视频讲解,而对于文字讲解也会相应地加以调整,重点在于根据笔者自己的理解给出习题的解析。因此带来的讲解不到位敬请见谅。


(本章请即将开始搭建 CPU 时再进行阅读)

测试程序设计

程序设计要点

  • 首先,要明确 CPU 支持哪些指令,我们的测试程序中使用到的指令不能超出 CPU 支持的范围

  • 对于测试程序而言,我们追求的并不是过程与结果有多么巧妙,我们的目的只有一个,那就是全面的测试每条指令。比如测试加法,我们就要把正正相加,负负相加,正负相加的情况都考虑到。

  • 在用 Mars 编写测试程序时,对于一些伪指或看起来合法(但其实不合法,比如立即数溢出)的指令,MARS 会自动将其拆解转换成若干条基本指令,这样就违背了设计的初衷,如下图。所以将代码导入到 CPU 中测试之前,一定要注意下这个问题。

在这里插入图片描述

测试样例

假设我们已经设计好了一个 CPU 程序,它支持 ori, lui, add, lw, sw, beq 这些指令,现在我们要写个测试程序来测试我们 CPU 程序的正确性(暂不考虑延迟槽)。

测试程序从哪条指令开始呢

首先我们必须要知道,测试程序的第一步一定是测试最基本的指令,只有基本指令正确了,我们才可以测试更复杂的指令。这些最基本的指令一般都是在测试时能够不依赖其他类型的指令就能判断指令正确性的指令,比如 oriluiaddi 等。

比如这里,我们要先测 orilui 指令,因为其他指令都得靠这两条指令为寄存器赋值,然后才能测试,不然寄存器的值都是 0,无法进行测试。

ORI 指令

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第1张图片

第一条我们先测最基本的,与 0 进行 or 运算,然后第二条再测试两个非 0 数直接的 or 运算。从指令集的解释中,我们知道,ori 指令的第三个立即数参数是无符号扩展,所以就不存在负数的情况。

LUI 指令

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第2张图片

根据指令集对 lui 的介绍,其实我们只有测第一条指令就行了,后面两条指令是为了使用 orilui 这两条指令构造一个负数,用于后面 add 指令的测试。

ADD 指令

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第3张图片

对于 add 指令,我们利用之前 orilui 准备好的寄存器进行这三种情况的测试。

SW 指令

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第4张图片

对于 swlw 指令,我们得先测 sw 往内存中存数据,这样才能通过 lw 取数据,不然内存中数据都是 0,lw 指令对不对我们也看不出来。

这里我用了这么多 sw 指令,主要是为了把之前的数据先保存下来,释放寄存器

LW 指令

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第5张图片

这里我们正好用之前 sw 存入内存的数据进行测试,最后再将结果存入内存,释放寄存器。

BEQ 指令

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第6张图片

这里把判断成立与不成立的情况都考虑了一遍,最终我们只要看内存中的数据就可以判断 beq 指令有没有正确的跳转。

结果测试

在我们的程序中,已经把所有有用的数据都存入到了内存中。所以只要将汇编程序对应的二进制码导入到 CPU 中,运行之后查看其内存中的数据,和 Mars 运行结果一比较,我们就可以看出程序有没有错。

测试程序的使用

说明

本讲将会介绍如何在 logsim 搭建的 CPU 电路使用 Verilog 语言编写的 CPU 工程文件中使用测试程序验证 CPU 的正确性。

LOGSIM 搭建的 CPU 电路

  1. 准备测试程序
  • 使用 Mars 编写测试程序,以 16 进制格式导出。
  • 在导出的 .txt 文件的首行加上 v2.0 raw
  • 文件样例

2.导入到 IFU 模块中的 ROM 中

  • IFU 模块中的 ROM 其实就是 IM,用来存储 CPU 将要执行的指令的集合。
  • 导入步骤:

(1) 选中 ROM 元件,右键 -> Edit Contents

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第7张图片

(2) 在弹出的编辑框中点击 Open 导入我们准备好的测试程序。

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第8张图片

3.运行 CPU 电路

  • 选择菜单栏 Simulate -> Ticks Enabled 运行 CPU 电路。

4.检查结果

  • 检查 GPR 模块中各个寄存器的值是否与预期的相同。
  • 检查 DM 模块中内存数据的值是否与预期的相同。
  • 测试程序预期的结果可以使用 Mars 查看。

VERILOG 语言编写的 CPU 工程文件

1.准备测试程序

  • Verilog 编写的 CPU 程序可以直接使用 Mars 导出的 16 进制机器码文件,不需要额外的修改。

2.导入到 IM 中

  • 在前期,我们是使用 reg 数组来模拟 ROM 存储指令的,比如 reg [31:0] im[1023:0] 就是一个可以存储 1024 条指令的 reg 数组,每个数组元素是 32 位,也就是一条指令的大小,数组下标是 0~1023。
  • 我们向数组中存储数据时使用的是系统函数 $readmemh

(1) 格式:$readmemh(“file”, mem_name, start_addr, stop_addr)

(2) file 是导入的 16 进制测试文件,不使用绝对路径时要将其放在工程文件下。

(3) mem_name 是我们存储元件的名字,这里就是数组的名字 im

(4) start_addr 和 stop_addr 是测试文件导入到存储元件中的起始地址和终止地址,在这里就是数组的下标,是可选参数。

  • 样例:$readmemh("code.txt", im);

(1) code.txt 是测试文件,im 是 reg 数组名。

(2)因为 im 数组大小为 4KB,所以提取指令时只需要用到 32 位地址中的前 12 位。相对于我们设置的起始地址 0x0000_3000 而言,前 12 位都是 0,所以指令正好是从数组的首个元素开始存储。因此,这里就不用地址参数了。

3.运行 CPU 程序

  • 选中工程文件 -> Simulata Behavioral Modul

4.检查结果

  • 在 Isim 界面左侧选择 Memory 选项,即可选择查看 GPR、DM、IM 中的数据。

北航计算机组成原理课程设计-2021秋 PreProject-MIPS-测试程序设计_第9张图片

指令编写测试

负数构造方法

在编写测试程序时,利用有限的指令去构造指定的数据也是很重要的。

比如我们只能使用ori和lui指令(必须是标准指令),如何去构造一个负数呢?

从下列选项中选择能够使$a0值为-1的选项?

A. ori $a0,$0,0xffffffff

B. ori $a0,$0,0xffff lui $a0,0xffff

C. lui $a0,0xffff ori $a0,$a0,0xffff

D. lui $a0,-1

答案:C

寄存器预处理判断

在我们的CPU设计中,所有的寄存器不用经预处理就可以与mars的行为保持一致?

A. 对

B. 错

答案:B

ori指令立即数大小范围

假如我们的CPU只支持 ori 指令,我们先会使用Mars编写测试程序,并将其导出到CPU上运行。下面会给出在Mars上编写的测试指令,试问,哪条指令能够在CPU上正确的运行呢?

A. ori $a0,$0,-1

B. ori $a0,$0,60000

C. ori $a0,$0,70000

D. or $a0,$0,$0

答案:B

你可能感兴趣的:(计算机组成,buaa,mips)