(一)从零开始设计RISC-V处理器——指令系统
(二)从零开始设计RISC-V处理器——单周期处理器的设计
(三)从零开始设计RISC-V处理器——单周期处理器的仿真
(四)从零开始设计RISC-V处理器——ALU的优化
(五)从零开始设计RISC-V处理器——五级流水线之数据通路的设计
(六)从零开始设计RISC-V处理器——五级流水线之控制器的设计
(七)从零开始设计RISC-V处理器——五级流水线之数据冒险
(八)从零开始设计RISC-V处理器——五级流水线之控制冒险
(九)从零开始设计RISC-V处理器——五级流水线之分支计算前移
(十)从零开始设计RISC-V处理器——五级流水线之静态预测
上一篇文章介绍了单周期CPU的实现,本篇文章进行功能仿真
(目前单周期处理器代码已经更新完成,点击链接直达:基于RISC-V指令集的单周期处理器的设计)
包含lui,auipc两条指令。
测试代码如下:
lui x1,0xfffff
addi x2,x0,0xff
slli x3,x2,4
addi x3,x3,0xf
add x4,x3,x1
auipc x5,0xfff
包含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
包含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
包含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
包含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
包含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