tiny - riscv - 补全R型和I型指令

211 阅读1分钟

image.png

算术指令I型 imm 立即数相关

image.png 编码方式和ADDI相同:

addi 立即数相加

xori 异或

ori 或

ANDI 与

slti 有符号比较 rs1<imm, 把rd设置为1,否则为0.

sltui 无符号比较。

编码方式相同:

SLLI: 逻辑左移

SRLI:逻辑右移

SRAI: 算术右移

算术右移:数字向右移动,左边补符号位

逻辑右移:数字向右移动,左边补0。

R型寄存器相关,I型立即数imm相关,U型 lui立即数加载,B型条件跳转分支指令

J型跳转指令。

image.png

立即数: 加法 有符号数比较 无符号数比较 异或 或 与 逻辑左移 算术右移 逻辑右移

					`INST_ADDI:begin
						rd_data_o = op1_i + op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end
					`INST_SLTI:begin
						rd_data_o = {30'b0,op1_i_less_op2_i_signed};
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end					
					`INST_SLTIU:begin
						rd_data_o = {30'b0,op1_i_less_op2_i_unsigned};
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end					
					`INST_XORI:begin
						rd_data_o = op1_i ^ op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end					
					`INST_ORI:begin
						rd_data_o = op1_i | op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end					
					`INST_ANDI:begin
						rd_data_o = op1_i & op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;
					end	
					`INST_SLLI:begin
						rd_data_o = op1_i << shamt;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;					
					end
					`INST_SRI:begin
						if(func7[5] == 1'b1) begin //SRAI
							rd_data_o = ((op1_i >> shamt) & SRA_mask) | ({32{op1_i[31]}} & (~SRA_mask));
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;							
						end
						else begin //SRLI
							rd_data_o = op1_i >> shamt;
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;							
						end
					end				

补全R型指令

寄存器 加法 减法 有符号数比较 无符号数比较 异或 或 与 逻辑左移 逻辑右移 算术右移

INST_ADD_SUB,INST_SLL,INST_SLT,INST_SLTU,INST_XOR,INST_SR,INST_OR,INST_AND

SLL 逻辑左移

SLT SLTU: 有符号比较 无符号比较

XOR 异或

OR 或

ADN 与

					`INST_ADD_SUB:begin
						if(func7[5] == 1'b0)begin//add
							rd_data_o = op1_i + op2_i;
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;
						end
						else begin
							rd_data_o = op1_i - op2_i;
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1; 								
						end
					end
					`INST_SLL:begin
						rd_data_o = op1_i << op2_i[4:0];
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end
					`INST_SLT:begin
						rd_data_o = {30'b0,op1_i_less_op2_i_signed};
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end
					`INST_SLTU:begin
						rd_data_o = {30'b0,op1_i_less_op2_i_unsigned};
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end
					`INST_XOR:begin
						rd_data_o = op1_i ^ op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end	
					`INST_OR:begin
						rd_data_o = op1_i | op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end
					`INST_AND:begin
						rd_data_o = op1_i & op2_i;
						rd_addr_o = rd_addr_i;
						rd_wen_o  = 1'b1;	
					end	
					`INST_SR:begin
						if(func7[5] == 1'b1) begin //SRA
							rd_data_o = ((op1_i >> op2_i[4:0]) & SRA_mask) | ({32{op1_i[31]}} & (~SRA_mask));
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;							
						end
						else begin //SRL
							rd_data_o = op1_i >> op2_i[4:0];
							rd_addr_o = rd_addr_i;
							rd_wen_o  = 1'b1;							
						end	
					end