RISCV架构单周期CPU设计

指令选取

R类型指令

31-2524-2020-1915-1411-76-0
funct7rs2rs1funct3rdopcode

编号 指令 名称
1 add rd, rs1, rs2 加
2 and rd, rs1, rs2 与
3 or rd, rs1, rs2 取或
4 xor rd, rs1, rs2 异或
5 srl rd, rs1, rs2 逻辑右移
6 sll rd, rs1, rs2 逻辑左移
7 slt rd, rs1, rs2 小于则置位
8 sltu rd, rs1, rs2 无符号小于则置位
9 div rd, rs1, rs2 除法
10 divu rd, rs1, rs2 无符号除法
11 mul rd, rs1, rs2 乘
12 mulh rd, rs1, rs2 高位乘
13 mulhsu rd, rs1, rs2 高位有符号-无符号乘.
14 mulhu rd, rs1, rs2 高位无符号乘
15 rem rd, rs1, rs2 求余数
16 remu rd, rs1, rs2 求无符号数的余数
17 sra rd, rs1, rs2 算术右移
18 sub rd, rs1, rs2 减

I类型指令

31-2019-1514-1211-76-0
funct7rs1funct3rdopcode

编号 指令 名称
19 addi rd, rs1, immediate 加立即数
20 ori rd, rs1, immediate 或立即数
21 andi rd, rs1, immediate 与立即数
22 slli rd, rs1, shamt 立即数逻辑左移
23 slti rd, rs1, immediate 小于立即数则置位
24 sltiu rd, rs1, immediate 无符号小于立即数则置位
25 srai rd, rs1, shamt 立即数算术右移
26 xori rd, rs1, immediate 立即数异或
27 lb rd, offset(rs1) 字节加载
28 lbu rd, offset(rs1) 无符号字节加载
39 lh rd, offset(rs1) 半字加载
30 lhu rd, offset(rs1) 无符号半字加载
31 lw rd, offset(rs1) 字加载
32 lwu rd, offset(rs1) 无符号字加载
33 jalr rd, offset(rs1) 跳转并寄存器链接

U类型指令

31-1211-76-0
imm[31:12]rdopcode

编号 指令 名称
34 auipc rd, immediate PC 加立即数
35 lui rd, immediate 高位立即数加载

S类型指令

31-2524-2019-1514-1211-76-0
imm[11:5]rs2rs1funct3imm[4:0]opcode

编号 指令 名称
36 sw rs2, offset(rs1) 存字
37 sb rs2, offset(rs1) 存字节
38 sh rs2, offset(rs1) 存半字

B类型指令

3130-2524-2019-1514-1211-88-76-0
imm[12]imm[10:5]rs2rs1funct3imm[4:1]imm[11]opcode

编号 指令 名称
39 beq rs1, rs2, offset 相等时分支
40 bge rs1, rs2, offset 大于等于时分支
41 bgeu rs1, rs2, offset 无符号大于等于时分支
42 blt rs1, rs2, offset 小于时分支
43 bltu rs1, rs2, offset 无符号小于时分支
44 bne rs1, rs2, offset 不相等时分支

J类型指令

3130-212019-1211-76-0
imm[20]imm[10:1]imm[11]imm[19:12]rdopcode

编号 指令 名称
45 jal rd, offset 跳转并链接

各部件功能设计

取指

PC

主要功能描述:时钟每翻转一次 PC 就会指向下一条指令的地址。
部分代码逻辑:

always @(posedge clk) begin
if(~clear)
nowPc<=32'b0;
else
nowPc<=nextPc;
end

pcAdder

主要功能描述: PC 的加法器,控制下一条指令的地址是否要加上立即数,即判断是否要跳转并执行 PC 指针的跳转,输入当前指令地址(nowPc)、立即数(imm)和判断条件(branch、zero…),输出下一条指令的地址(nextPc)。
部分代码逻辑:

always @(*) begin
if(branch==2'b01&&(zero||jump))
nextPc<=nowPc+imm;
else if(branch==2'b10&&(~zero||jump))
nextPc<=nowPc+imm;
else if(branch==2'b11&&result)
nextPc<=nowPc+imm;
else if(jump)
nextPc<=nowPc+imm;
else
nextPc<=nowPc+4'h4;
end

inst Mem

主要功能描述:存储指令的寄存器,输入一个 32 位的指令地址,输出一条 32 位的指令。
部分代码逻辑:

always @(*) begin
if(~clear)
instruct<=0;
else
instruct<=instMem_text[address[9:2]];
end

译码

ID

主要功能描述:指令译码器,输入一条指令(instruct),输出整个 CPU 所有外部控制信号的取值。
部分代码逻辑:

case(f7)
7'b0000000: begin
case(f3)
3'b000: begin
alu_ctr_o <= 6'b000000; //add
end
3'b111: begin
alu_ctr_o <= 6'b000001; //and
end
3'b110: begin
alu_ctr_o <= 6'b000010; //or
end
3'b100: begin
alu_ctr_o <= 6'b000011; //xor
end
3'b101: begin
alu_ctr_o <= 6'b000100; //srl
end
3'b001: begin
alu_ctr_o <= 6'b000101; //sll
end
9
3'b010: begin
alu_ctr_o <= 6'b000110; //slt
end
3'b011:begin
alu_ctr_o <= 6'b000111; //sltu
end
endcase
end

访存

regFile

主要功能描述:寄存器堆,用于读取或存储寄存器,输入读取或存储的地址以及使能信号,输出读出的数据。
部分代码逻辑:

always @(*) begin//读
if(~rstn)begin
Rdata1<=32'b0;
Rdata2<=32'b0;
end
else begin
Rdata1<=regF[Radd1];
Rdata2<=regF[Radd2];
end
end

立即数扩展

IE

主要功能描述:立即数扩展器,输入指令(instruct)和立即数扩展的控制信号(exop)输出扩展后的 32 位立即数(imm)。
部分代码逻辑:

3'b100: begin // jal
imm <= {{12{instruct[31]}}, instruct[19:12], instruct[20],
instruct[30:21], 1'b0};
end
3'b101: begin // slli
imm <= {{27{instruct[31]}}, instruct[24:20]};
end
3'b110: begin // 无符号扩展 31:20 立即数
imm <= {20'b0 , instruct[31:20]};
end

ALU

主要功能描述:算数处理单元,两个数据输入端口(rs1、rs2),一个控制信号端口(ALUctr),输出计算结果
部分代码逻辑:

6'b000011:begin
res<=rs1^rs2;
end
6'b000100:begin
res<=rs1>>rs2;
end
6'b000101:begin
res<=rs1<<rs2;
end
6'b000110:begin
if(rs1<rs2)res<=32'b0000_0000_0000_0000_0000_0000_0000_000
1;
else res<=0;
end
6'b000111:begin
if(rs1<rs2)res<=32'b0000_0000_0000_0000_0000_0000_0000_000
1;
else res<=0;

存储器

主要功能描述:存储器,用于存储和读取数据的单元,输入为 32 位地址(address),32 位要存储的数据(dataW),以及一个使能信号,输出为 32 位读出的数据(dataR),由于存储器不能同时读取和存储,所以只要一个地址就行了。
部分代码逻辑:

always @(posedge clk or negedge rstn) begin
if(rstn&&isWmem)
mem[address[9:2]]<=dataW;
end
always @(*) begin
if(~rstn)
dataR<=32'b0;
else
12
dataR<=mem[address[9:2]];
end

多路选择器

主要功能描述:多路选择器,选择 rs1 还是 pc 的值到 ALU 进行计算,输入两个值和控制信号,输出选择后的值。
部分代码逻辑:

case (mrs1andpc_ctr)
1'b0:begin
mrs1andpc_out<=rs1;
end
1'b1:begin
mrs1andpc_out<=pc;
end
endcase

主要功能描述:多路选择器,选 rs2 还是立即数(imm)到 ALU 进行计算,输入两个值和控制信号,输出选择后的值。
部分代码逻辑:

case (mrs2andie_ctr)
13
2'b00:begin
mrs2andie_out<=rs2;
end
2'b01:begin
mrs2andie_out<=4'h4;
end
2'b10:begin
mrs2andie_out<=imm;
end
endcase

主要功能描述:多路选择器,选 pc 还是 rs1 的值到 pc,此选择器用于特定 J 型指令 jalr,输入为两个值和控制信号,输出为选择的值。
部分代码逻辑:

case(mrs1andpc_ctr2)
1'b0:begin
mrs1andpc_out<=pc;
end
1'b1:begin
mrs1andpc_out<=rs1;
end
endcase

主要功能描述:变化 rs2 送到存储器,因为有指令需要变化存储前数据的位数,所以设置此器件,输入为一个数据值和控制信号,输出为要送到存储器的值。
部分代码逻辑:

case (mrs2_ctr)
1'b00:begin
mrs2_out<=rs2;
end
2'b01:begin
mrs2_out <= {{24{rs2[7]}}, rs2[7:0]};
end
2'b11:begin
mrs2_out <= {{16{rs2[15]}}, rs2[15:0]};
end
endcase

主要功能描述:多路选择器,选择 ALU 的输出还是存储器的输出送到寄存器,此选择器区分 load 等指令和其他指令,输入为两个数据值和控制信号,输出为要送到寄存器的值。
部分代码逻辑:

case (maluandmem_ctr)
3'b000:begin
maluandmem_out<=ALU_result;
end
3'b001:begin
maluandmem_out<=mem_data;
end
3'b010: begin
maluandmem_out <= {{24{mem_data[7]}}, mem_data[7:0]};
end
3'b011: begin
16
maluandmem_out <= {{16{mem_data[15]}}, mem_data[15:0]}
;
end
3'b100: begin
maluandmem_out <= {24'b0, mem_data[7:0]};
end
3'b101: begin
maluandmem_out <= {16'b0, mem_data[15:0]};
end
endcase
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值