riscvCPU实现 1 译码模块
在本模块中,将指令进行译码,输出opcode, func3, func7, Rs1, Rs2, Rd以及符号扩展后的32位imme
//输入输出信号
input [31:0]instr,
output [6:0]opcode,
output [2:0]func3,
output func7,
output [4:0]Rs1,
output [4:0]Rs2,
output [4:0]Rd,
output [31:0]imme
1.0 riscv基本指令
R 型指令,用于寄存器-寄存器操作
I 型指令,用于短立即数操作, 访存 load 操作
S 型指令,用于访存 store 操作
B 型指令,用于条件跳转操作
U 型指令,用于长立即数
J 型指令,用于无条件跳转
指令格式如下:
1.1 R 类型指令
R型指令将32位划分成6个区域:
opcode是操作码,占了7bit,在指令格式的0-6bit位上
rd 是目的寄存器,占了5bit,在指令格式的7-11bit位上
funct3+funct7是两个操作字段。funct3占了3bit,在指令格式的12-14bit位上;funct7占了7bit,在指令格式的25-31bit位上。
rs1 是第一个源操作数寄存器,占了5bit,在指令格式的15-19bit位上。
rs2 是第二个源操作数寄存器,占了5bit,在指令格式的25-31bit位上。
1.2 I型指令
短立即数指令
加载指令
无条件跳转JALR指令
1.3 S型指令
S类型的全部指令
1.4 B型指令
1.5 U型指令
U类型指令包含两种指令
1.LUI – 加载高位立即数
2.AUIPC – 立即数地址添加到PC寄存器中
1.6 J型指令
1.7 立即数符号扩展
//立即数符号扩展
assign I_imme={{20{instr[31]}},instr[31:20]};
assign U_imme={instr[31:12],{12{1'b0}}};
assign J_imme={{12{instr[31]}},instr[19:12],instr[20],instr[30:21],1'b0};
assign B_imme={{20{instr[31]}},instr[7],instr[30:25],instr[11:8],1'b0};
assign S_imme={{20{instr[31]}},instr[31:25],instr[11:7]};
assign imme= I_type ? I_imme : U_type ? U_imme : J_type ? J_imme : B_type ? B_imme : S_type ? S_imme : 32'd0
1.8 指令与opcode
//U
`define lui 7'b0110111
`define auipc 7'b0010111
//J
`define jal 7'b1101111
//I
`define I_type 7'b0010011
`define jalr 7'b1100111
`define load 7'b0000011
//B
`define B_type 7'b1100011
//S
`define store 7'b0100011
//R
`define R_type 7'b0110011
verilog代码
`include "define.v"
module InstrDecode(
input [31:0]instr,
output [6:0]opcode,
output [2:0]func3,
output func7,
output [4:0]Rs1,
output [4:0]Rs2,
output [4:0]Rd,
output [31:0]imme
);
wire I;
wire U;
wire J;
wire B;
wire S;
wire [31:0]I_imme;
wire [31:0]U_imme;
wire [31:0]J_imme;
wire [31:0]B_imme;
wire [31:0]S_imme;
//R型指令译码
assign opcode=instr[6:0];
assign func3=instr[14:12];
assign func7=instr[30];
assign Rs1=instr[19:15];
assign Rs2=instr[24:20];
assign Rd =instr[11:7];
assign I=(instr[6:0]==`jalr) | (instr[6:0]==`load) | (instr[6:0]==`I_type);
assign U=(instr[6:0]==`lui) | (instr[6:0]==`auipc);
assign J=(instr[6:0]==`jal);
assign B=(instr[6:0]==`B_type);
assign S=(instr[6:0]==`store);
//立即数符号扩展
assign I_imme={{20{instr[31]}},instr[31:20]};
assign U_imme={instr[31:12],{12{1'b0}}};
assign J_imme={{12{instr[31]}},instr[19:12],instr[20],instr[30:21],1'b0};
assign B_imme={{20{instr[31]}},instr[7],instr[30:25],instr[11:8],1'b0};
assign S_imme={{20{instr[31]}},instr[31:25],instr[11:7]};
assign imme= I_type ? I_imme : U_type ? U_imme : J_type ? J_imme : B_type ? B_imme : S_type ? S_imme : 32'd0
endmodule
参考文档
https://blog.csdn.net/qq_38915354/article/details/115696721
https://whycan.com/files/members/7090/riscv-spec-v2.1中文版.pdf
https://blog.csdn.net/qq_45677520/article/details/122386632?spm=1001.2014.3001.5502