实现整数运算指令

实验目的

(1)理解Ⅰ型和R型整数运算指令指令功能;

(2)理解数据通路与指令功能的关联;

(3)掌握硬布线控制逻辑的设计方法;

(4)进一步掌握CPU实验的调试方法。

实验原理

前面ADDI指令的参考设计没有ALU模块,只能进行加法运算,为了实现更多的I型运算指令,需要添加ALU模块;参考设计只能是rs1加立即数,而R型运算指令和I型运算指令的区别在于第二个运算数的来源不同,I型指令是立即数,R型指令是寄存器,所以增加一个多路器进行选择,数据通路如图 1

SingleCycleRISCV_07_SC-I-R 300dpi
图 1. ADDI指令的数据通路

实验步骤

1. 增加ALU模块

将前面实验中自己设计的ALU模块添加到工程中。

(1)机器考核按表 1规定的ALUop进行测试。

表 1. ALUop编码表

ALUop

功能描述

0001

加法

0010

减法

0011

按位逻辑与

0100

按位逻辑或

0101

按位逻辑异或

0110

算术右移

0111

逻辑左移

1000

逻辑右移

(2)移位运算的移位位数最多31位。

(3)ALUop的编码使用package中定义的枚举常量。

2. 设计控制逻辑

修改Controller模块,增加ImmToALU控制信号, 产生ALUop控制信号。

(1)I型和R型指令共用Funct译码逻辑。

虽然I型和R型指令的opcode不同,但Funct3、Funct7的编码基本相同。可以考虑这两类指令共用Funct译码逻辑,减少硬件资源占用。

注意少数指令的Funct3相同,由Funct7区分,如逻辑右移指令和算术右移指令,加法和减法指令。

(2)输出的ALUop编码使用package中定义的枚举常量。

在控制器模块和ALU模块中使用同一个package定义的枚举常量,有利于避免编码不一致产生错误。

(3)“不关心”的控制信号。

R型指令与立即数无关,理论上立即数类型以及生成的立即数对指令结果没有影响。由于实验平台根据控制信号绘制动态信息流显示,为避免显示错误的信息流,建议R型指令的ImmType为0,并且生成的立即数为0。

3. 连接CPU数据通路

实例化ALU模块,添加多路器;根据Controller模块的修改增加ALUop端口连接,连接增加的控制信号。

4. 增加调试支持代码

验证任务提供了设计好的虚拟面板,和ADDI指令的参考设计相比,增加ImmToALU、ALUop等观察信号和RD2等观察数据。需要做的是在代码中增加相应的调试支持,注意序号和位宽一定要和虚拟面板一致,例 1给出与虚拟面板对应的ws和wd结构体定义。

例 1. 与虚拟面板对应的ws和wd结构体定义
    //送给调试器的观察信号,需要与虚拟面板的信号框相对应
    struct packed{
        logic [3:0] WS3;    //ALUop
        logic [4:0] WS2;    //Imm_type
        //以下观察信号用于电路测试,请勿修改! (1)
        logic       WS1;    //ImmToALU
        logic       WS0;    //RegWrite
    }ws;

    //送给调试器的观察数据,需要与虚拟面板的数据框相对应
    struct packed{        
        logic [31:0] WD9;   //nextPC
        logic [31:0] WD8;   //regReadData2
        logic [4:0]  WD7;   //ra2
        logic [31:0] WD6;   //immData    
        //以下观察数据用于电路测试,请勿修改! (2)
        logic [31:0] WD5;   //regWriteData
        logic [4:0]  WD4;   //wa
        logic [31:0] WD3;   //regReadData1
        logic [4:0]  WD2;   //ra1
        logic [31:0] WD1;   //instruction
        logic [31:0] WD0;   //pc
    }wd;

① ② 虽然电路测试需要的观察信号和观察数据较少,但更多的观察变量可帮助理解指令执行过程,有利于调试硬件;如果需要更多的观察变量,也可自行添加。多出的观察变量不会影响电路测试,提交电路测试时无需删除。

4. 在实验平台验证设计

根据ALU所实现的运算功能,执行相应的Ⅰ型和R型运算指令,并检查指令执行结果。 参考测试程序如下。 将测试程序用RISC-V汇编器(如Ripes)翻译成机器指令,输入实验系统后运行。

(1)Ⅰ型运算指令的参考测试程序

    # I型运算指令测试
	.text
    addi x0, x0, -1      
    addi x17, x0, 0x555
    slli x17, x17, 20
    ori  x17, x17, 0x555  
    addi x10, x0, -0x667  
    slli x11, x10, 20     
    ori  x18, x11, 0x666  
    andi x19, x18, -0x556 
    addi x19, x19, 0      
    xori x21, x18, -1     
    addi x21, x21, 0      
    srai x22, x18, 12     
    addi x22, x22, 0      
    srli x23, x18, 31     
    addi x23, x23, 0      
    srai x24, x17, 16     
    addi x24, x24, 0      
    srli x25, x17, 30     
    addi x25, x25, 0      

(2)R型运算指令的参考测试程序

    # R型运算指令测试
    .text
    addi x17, x0, 0x555
    slli x17, x17, 20
    ori  x17, x17, 0x555 
    addi x10, x0, -0x667 
    slli x11, x10, 20    
    ori  x18, x11, 0x666 
    and  x19, x18, x17   
    addi x19, x19, 0     
    or   x20, x18, x17   
    addi x20, x20, 0     
    xor  x21, x18, x17   
    addi x21, x21, 0     
    add  x22, x18, x17   
    addi x22, x22, 0     
    sub  x23, x18, x17   
    addi x23, x23, 0     
    addi x28, x0, 21    
    sll  x5, x18, x28    
    addi x5, x5, 0       
    addi x28, x0, 12
    sra  x6, x18, x28    
    addi x6, x6, 0       
    srl  x7, x18, x28    
    addi x7, x7, 0       
    addi x28, x0, 36     
    sra  x8, x17, x28    
    addi x8, x8, 0       
    srl  x9, x17, x28    
    addi x9, x9, 0       

(3)编写自己的测试程序

编写一个综合Ⅰ型和R型运算指令的测试程序,验证自己的设计。根据指导教师的要求,提交验证记录。

测试程序输入到实验系统后,应及时保存到本地备份。

5. 提交电路测试

将验证正确的电路提交测试。

测试任务的虚拟面板所包含的观察信号和观察数据较少,但无需将设计代码中的观察变量减少到和虚拟面板一样,不会因此影响测试的分数。