从零开始设计RISC-V处理器——单周期处理器的仿真

系列文章目录

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



前言

上一篇文章介绍了单周期CPU的实现,本篇文章进行功能仿真
(目前单周期处理器代码已经更新完成,点击链接直达:基于RISC-V指令集的单周期处理器的设计


一、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条指令进行逐条仿真,在设计仿真的指令时要注意测试的完备性,比如正数的加减法,负数的加减法,正数与负数的加减法,溢出检测,进位检测等。 下一篇文章开始对处理器进一步优化。
  • 12
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
ALU(算术逻辑单元)是计算机处理器中负责执行算术和逻辑操作的核心组件。在设计RISC-V处理器的过程中,ALU的优化是至关重要的一步。 首先,我们可以通过增加多个ALU管道来提高处理器的性能。这样,指令可以在多个ALU之间并行执行,从而加快处理速度。另外,还可以采用超标量技术,将多个ALU分组,并行执行不同的指令,进一步提高处理器效率。 其次,为了提高ALU的性能,我们可以通过增加更多的功能单元来支持多种操作。例如,我们可以添加浮点运算单元,以支持浮点运算指令。此外,还可以添加位移单元和乘法单元等,以执行各种操作。通过提供更多的功能单元,ALU可以在单个周期内执行更多的操作,提高处理器的性能。 另外,在ALU的设计中,还需要考虑到电路延迟的问题。通过优化电路布线和信号传输路径,可以减少ALU操作所需的时间。此外,采用流水线技术也可以提高处理器的吞吐量。通过将ALU操作划分为多个阶段,并行执行多条指令,可以大大提高处理器的效率。 最后,为了优化ALU的设计,还需要考虑功耗的问题。通过采用低功耗电路设计和节能技术,可以有效降低ALU的功耗。此外,在处理器设计过程中,还可以采用动态电压调整和时钟频率调整等技术,根据实际负载情况动态调整ALU的电压和频率,以达到节能的目的。 综上所述,通过增加ALU管道、添加更多功能单元、优化电路延迟、采用流水线技术和优化功耗等方法,可以对RISC-V处理器中的ALU进行优化,提高处理器的性能和效率。这些优化措施能够使处理器更快、更强大,更适应各种复杂的计算任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不学无术的小胖子.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值