irpas技术客

从零开始设计RISC-V处理器——单周期处理器的仿真_不学无术的小胖子._单周期处理器

网络 1502

系列文章目录

(一)从零开始设计RISC-V处理器——指令系统 (二)从零开始设计RISC-V处理器——单周期处理器的设计 (三)从零开始设计RISC-V处理器——单周期处理器的仿真 (四)从零开始设计RISC-V处理器——ALU的优化 (五)从零开始设计RISC-V处理器——五级流水线之数据通路的设计 (六)从零开始设计RISC-V处理器——五级流水线之控制器的设计 (七)从零开始设计RISC-V处理器——五级流水线之数据冒险 (八)从零开始设计RISC-V处理器——五级流水线之控制冒险 (九)从零开始设计RISC-V处理器——五级流水线之分支计算前移 (十)从零开始设计RISC-V处理器——五级流水线之静态预测


文章目录 系列文章目录前言一、U-type测试二、跳转指令测试三、访存指令测试四、算数运算指令测试五、逻辑运算指令测试六、移位运算指令测试七、小于置一指令测试总结


前言

上一篇文章介绍了单周期CPU的实现,本篇文章进行功能仿真


一、U-type测试

包含lui,auipc两条指令。 测试代码如下:

lui x1,0xfffff addi x2,x0,0xff slli x3,x2,4 addi x3,x3,0xf add x4,x3,x1 auipc x5,0xfff

汇编器执行结果如下: CPU的仿真波形如下:

二、跳转指令测试

包含jal,jalr,beq,bne,blt,bge,bltu,bgeu共8条指令。 测试代码如下:

addi x1,x0,1 addi x2,x0,2 jal x31,label1 addi x3,x0,3 label1: addi x4,x0,4 add x5,x2,x2 beq x4,x5,label2 addi x6,x0,6 label2: bne x4,x5,label3 addi x7,x0,7 label3: bne x7,x6,label4 addi x8,x0,8 label4: addi x9,x0,0x30 jalr x10,x9,12 addi x11,x0,11 addi x12,x0,-12 addi x13,x0,-13 blt x13,x12,label5 addi x14,x0,-14 label5: bltu x13,x12,label6 addi x15,x0,-15 label6: bltu x12,x13,label7 addi x16,x0,-16 label7: bge x12,x13,label8 addi x17,x0,-17 label8: bge x1,x2,label9 addi x18,x0,-18 label9: bgeu x12,x13,label10 addi x19,x0,-19 label10: bgeu x13,x12,label11 addi x20,x0,-20 label11: addi x21,x0,-20 addi x22,x0,-20 bge x21,x22,label12 addi x23,x0,-23 label12: addi x24,x0,-24

以上代码在编写的过程中,在跳转指令与跳转目标地址的指令之间都至少插入了一条指令,目的是为了体现跳转与否。

汇编器执行结果如下:

CPU的仿真波形如下: 可以看到,在这里,给X7赋值之后后面的指令都没有正常运行。 这是 因为下一条指令是bne x7,x6,label4,由于X6是未知态,所以这条指令无法正确判断。所以我们暂时在寄存器堆模块给32个寄存器赋一个初始值0。 代码修改如下:

`include "define.v" //`define INITIAL module registers( clk, rst_n, W_en, Rs1, Rs2, Rd, Wr_data, Rd_data1, Rd_data2 ); input clk; input rst_n; input W_en; input [4:0]Rs1; input [4:0]Rs2; input [4:0]Rd; input [31:0]Wr_data; output [31:0]Rd_data1; output [31:0]Rd_data2; reg [31:0] regs [31:0]; ///write `ifdef INITIAL always@(posedge clk ) begin if(W_en & (Rd!=0)) regs[Rd]<=Wr_data; end `else always@(posedge clk ) begin if(!rst_n) begin regs[0]<=`zero_word; regs[1]<=`zero_word; regs[2]<=`zero_word; regs[3]<=`zero_word; regs[4]<=`zero_word; regs[5]<=`zero_word; regs[6]<=`zero_word; regs[7]<=`zero_word; regs[8]<=`zero_word; regs[9]<=`zero_word; regs[10]<=`zero_word; regs[11]<=`zero_word; regs[12]<=`zero_word; regs[13]<=`zero_word; regs[14]<=`zero_word; regs[15]<=`zero_word; regs[16]<=`zero_word; regs[17]<=`zero_word; regs[18]<=`zero_word; regs[19]<=`zero_word; regs[20]<=`zero_word; regs[21]<=`zero_word; regs[22]<=`zero_word; regs[23]<=`zero_word; regs[24]<=`zero_word; regs[25]<=`zero_word; regs[26]<=`zero_word; regs[27]<=`zero_word; regs[28]<=`zero_word; regs[29]<=`zero_word; regs[30]<=`zero_word; regs[31]<=`zero_word; end else if(W_en & (Rd!=0)) regs[Rd]<=Wr_data; end `endif //read assign Rd_data1=(Rs1==5'd0)?`zero_word: regs[Rs1]; assign Rd_data2=(Rs2==5'd0)?`zero_word: regs[Rs2]; endmodule

注意:此处由于仿真时寄存器的值是未知态,所以需要对寄存器赋初始值。在实际的设计中,这里是不需要进行赋初值的,因为CPU上电之后都会执行一段初始化代码。在FPGA开发板中,也是不需要赋初值的,因为FPGA开发板内部的寄存器上电会自动置零。

更改后的仿真波形如下:

三、访存指令测试

包含lb,lh,lw,lbu,lhu,sb,sh,sw共8条指令。 测试代码如下:

addi x1,x0,0x70 slli x2,x1,8 addi x1,x0,0x71 add x2,x2,x1 slli x2,x2,8 addi x1,x0,0xf2 add x2,x2,x1 slli x2,x2,8 addi x1,x0,0xf3 add x2,x2,x1 sw x2,0,x0 sh x2,4,x0 sb x2,7,x0 lb x3,0,x0 lb x4,1,x0 lb x5,2,x0 lb x6,3,x0 lbu x7,0,x0 lbu x8,1,x0 lbu x9,2,x0 lbu x10,3,x0 lh x11,0,x0 lh x12,2,x0 lh x13,4,x0 lhu x14,0,x0 lhu x15,2,x0 lhu x16,4,x0 lw x17,0,x0

汇编器执行结果如下: 寄存器堆:

数据存储器:

CPU的仿真波形如下:

四、算数运算指令测试

包含add,sub,addi共3条指令。 测试代码如下:

addi x1,x0,1 add x2,x1,x1 add x3,x2,x2 sub x3,x3,x1 addi x4,x0,-4 add x5,x4,x4 sub x6,x5,x3 sub x7,x6,x4 add x8,x7,x3

汇编器执行结果如下:

CPU的仿真波形如下:

五、逻辑运算指令测试

包含and,or,xor,andi,ori,xori六条指令。 测试代码如下:

addi x1,x0,0b00110011 addi x2,x0,0b11111100 and x3,x1,x2 or x4,x1,x2 xor x5,x1,x2 andi x6,x1,0b11111100 ori x7,x1,0b11111100 xori x8,x1,0b11111100

汇编器执行结果如下: CPU的仿真波形如下:

六、移位运算指令测试

包含sll,srl,sra,slli,srli,srai六条指令。 测试代码如下:

addi x1,x0,0xff addi x2,x0,4 sll x3,x1,x2 srl x4,x1,x2 sra x5,x1,x2 addi x6,x0,-0xff sll x7,x6,x2 srl x8,x6,x2 sra x9,x6,x2 slli x11,x1,4 srli x12,x1,4 srai x13,x1,4 slli x11,x6,4 srli x12,x6,4 srai x13,x6,4

汇编器执行结果如下:

CPU的仿真波形如下:

七、小于置一指令测试

包含slt,stlu,slti,sltiu四条指令。 测试代码如下:

addi x1,x0,-1 addi x2,x0,-2 addi x3,x0,3 addi x4,x0,4 slt x5,x1,x2 slt x6,x2,x1 slt x7,x3,x4 slt x8,x4,x3 sltu x9,x1,x3 sltu x10,x3,x1 sltu x11,x1,x2 slti x12,x3,-3 slti x13,x3,4 slti x14,x2,-1 slti x15,x2,-4 sltiu x16,x3,-3 sltiu x17,x3,4 sltiu x18,x2,-1 sltiu x19,x2,-4

汇编器执行结果如下:

CPU的仿真波形如下:

总结 以上就是今天的内容,对37条指令进行逐条仿真,在设计仿真的指令时要注意测试的完备性,比如正数的加减法,负数的加减法,正数与负数的加减法,溢出检测,进位检测等。 下一篇文章开始对处理器进一步优化。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #单周期处理器 #auipc两条指令