算术指令I型 imm 立即数相关
编码方式和ADDI相同:
addi 立即数相加
xori 异或
ori 或
ANDI 与
slti 有符号比较 rs1<imm, 把rd设置为1,否则为0.
sltui 无符号比较。
编码方式相同:
SLLI: 逻辑左移
SRLI:逻辑右移
SRAI: 算术右移
算术右移:数字向右移动,左边补符号位
逻辑右移:数字向右移动,左边补0。
R型寄存器相关,I型立即数imm相关,U型 lui立即数加载,B型条件跳转分支指令
J型跳转指令。
立即数: 加法 有符号数比较 无符号数比较 异或 或 与 逻辑左移 算术右移 逻辑右移
`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