Skip to content

实验测试

实验测试方法

首先,下载代码仓库的 master 分支:

cd 2022Spring/ # 选择一个合适的目录
git clone -b master https://github.com/FDUCSLG/Arch-2022Spring-FDU.git  #下载仓库的master分支
cd Arch-2022Spring-FDU
git submodule update --init --recursive
make test-lab1  #测试

代码编写

我们在 vsrc 里写 SystemVerilog 代码。

有以下要求:

  • 每个 .sv 文件仅编写一个 module

  • 文件名与 module 名一致,一般为全小写

  • 每个文件都要用 ifndef __NAME_SV 来保护

  • 每个文件都要有:

`ifdef VERILATOR
`else
`endif
  • verilator 仿真中,module 进行元件例化前,需要以vsrc/ 为根的相对路径 include 源文件,写在`ifdef VERILATOR 区域。

  • vivado 中,只需 include 头文件,include 时不写路径,只写文件名.svh 。

  • module 的一般形式:

module sample
    import common::*; #(
  parameter XLEN = 16
) (
  input logic clk, reset
);
endmodule

Verilator 仿真

这是我们主要的调试手段。

运行 make test-lab1 等测试,观察输出。如果有 Hit Good Trap 输出则为通过。

Vivado 仿真

请在 Verilator 仿真通过后再尝试 Vivado 仿真。

使用 Vivado2018.3 打开 vivado/test1/project/project_1.xpr ,点击 tools 下的Run Tcl Script 运行 vsrc/add_sources.tclvivado/src/add_source.tcl 添加源文件,然后 Run Simulation 。点击上方三角开始仿真。

Vivado 上板

请至少在 Verilator 仿真通过后再尝试上板。

点击 Generate Bitstream ,生成完毕后连接实验板并 Program Device 。

在电脑上打开串口软件 ( Windows 系统可使用 elearning 上发的 SecureCRT,其他系统请自行寻找相关软件),设置串口(Serial)波特率(Baud Rate)9600,然后连接。

按下实验板上的 prog ,可在串口软件中看到一行输出:BASYS3 GPIO/UART DEMO! 这是内置的 bitstream 的输出,不是我们 CPU 的输出。点击 Program Device 才是我们 CPU 的输出。

实验测试介绍

CPU 访存接口

流水线部分有指令内存接口与数据内存接口,CPU与内存的交互**只需要**这两个接口,定义在 include/common.sv ; 实现在 core.svinputoutput接口

指令内存接口:

typedef struct packed {
    logic  valid;  // in request? (Used in Lab 2)
    addr_t addr;   // target address
} ibus_req_t;

typedef struct packed {
    logic  addr_ok;  // is the address accepted by cache? (Used in Lab 2)
    logic  data_ok;  // is the field "data" valid?        (Used in Lab 2)
    u32 data;        // the data read from cache
} ibus_resp_t;

数据内存接口:

typedef struct packed {
    logic    valid;   // in request?
    addr_t   addr;    // target address
    msize_t  size;    // number of bytes                (Used in Lab 2)
    strobe_t strobe;  // which bytes are enabled? set to zeros for read request (in Lab 1, it is either '0(0x0) or '1(0xff))
    word_t   data;    // the data to write
} dbus_req_t;

typedef struct packed {
    logic  addr_ok;  // is the address accepted by cache?   (Used in Lab 2)
    logic  data_ok;  // is the field "data" valid?          (Used in Lab 2)
    word_t data;     // the data read from cache
} dbus_resp_t;

include与import

对于verilator,引用其它文件定义的结构或是模块都需要进行include

`ifdef VERILATOR
`include "文件相对于vsrc的路径"
`else
`endif

比如在core.sv中,不仅使用到了定义在common.sv中的ibusdbus,如果也用到了regfile.sv中定义的regfile模块,那么**都需要**进行include

`ifdef VERILATOR
`include "include/common.sv"
`include "pipeline/regfile/regfile.sv"
`else
`endif

而对于vivado,为了引用其它结构,需要在每个模块内import对应的package,但是使用其它文件定义的模块则不需要import,使用tcl脚本加入源文件后,vivado会自行找到,比如core.sv

module core
    import common::*;(
        input logic clk, reset,
        output ibus_req_t  ireq,
        ...
    );
endmodule

import了定义在common.sv中的名叫 common 的package,但是不需要import regfile,直接使用即可。

package common;
    ....
endpackage

接入Verilator仿真

将 CPU 接入 Verilator Difftest 的仿真接口。

需要例化三个模块(所给框架中已例化好,需要接线)。

首先是当前周期提交的指令:

DifftestInstrCommit DifftestInstrCommit(
    .clock              (clk),
    .coreid             (0), // 无需改动
    .index              (0), // 多发射时,例化多个该模块。前四个 Lab 无需改动它
    .valid              (0), // 无提交(或提交的指令是flush导致的bubble时,为0)
    .pc                 (0), // 这条指令的 pc
    .instr              (0), // 这条指令的内容,可不改动
    .skip               (0), // 提交的是一条内存读写指令,且这部分内存属于设备(addr[31] == 0)时,skip为1
    .isRVC              (0), // 前四个 Lab 无需改动
    .scFailed           (0), // 前四个 Lab 无需改动
    .wen                (0), // 这条指令是否写入通用寄存器,1 bit
    .wdest              (0), // 写入哪个通用寄存器
    .wdata              (0)  // 写入的值
);

这个周期的指令提交后,通用寄存器的内容(已连接好):

DifftestArchIntRegState DifftestArchIntRegState (
    .clock              (clk),
    .coreid             (0),
    .gpr_0              (regfile.regs_nxt[0]),
    // ...
);

这个周期的指令提交后,系统寄存器的内容(Lab4 的内容,前面的 Lab 可以不管):

DifftestCSRState DifftestCSRState(

);

生成波形图

不生成波形图时运行测试,使用make test-lab1;需要生成波形图,使用 make test-lab1 VOPT="--dump-wave",运行结束后可在 build 目录下看到波形图,使用 gtkwave 打开。

默认截取前 10^6 个时钟周期。如果需要调整,使用 make test-lab1 VOPT="--dump-wave -b <begin> -e <end>"