实现了RVI指令中除ori指令的其它指令。
RISCV指令集架构定义的基本整数指令RV32I有9条:
ADDI、SLTI、SLTIU、ANDI、ORI、XORI、SLLI、SRLI、SRAI
其格式如下
addi rd, rs1, imm[11:0]
指令详解:
addi指令将操作数rs1中的整数与12为立即数(进行符号位扩展)进行家吗操作,结果写回寄存器rd中。
在I指令定义的后面添加其它I类型指令
`define INST_ADDI 3'b000
`define INST_SLTI 3'b010
`define INST_SLTIU 3'b011
`define INST_XORI 3'b100
`define INST_ORI 3'b110
`define INST_ANDI 3'b111
`define INST_SLLI 3'b001
`define INST_SRI 3'b101
case (opcode)
`INST_TYPE_I: begin
case (funct3)
`INST_ADDI, `INST_SLTI, `INST_SLTIU, `INST_XORI, `INST_ORI, `INST_ANDI, `INST_SLLI, `INST_SRI: begin
reg_we_o = `WriteEnable;
reg_waddr_o = rd;
reg1_raddr_o = rs1;
reg2_raddr_o = `ZeroReg;
op1_o = reg1_rdata_i;
op2_o = {{20{inst_i[31]}}, inst_i[31:20]};
end
default: begin
reg_we_o = `WriteDisable;
reg_waddr_o = `ZeroReg;
reg1_raddr_o = `ZeroReg;
reg2_raddr_o = `ZeroReg;
end
endcase
end
...
case (opcode)
`INST_TYPE_I: begin
case (funct3)
`INST_ADDI: begin
reg_wdata = op1_add_op2_res;
end
`INST_SLTI: begin
reg_wdata = {32{(~op1_ge_op2_signed)}} & 32'h1;
end
`INST_SLTIU: begin
reg_wdata = {32{(~op1_ge_op2_unsigned)}} & 32'h1;
end
`INST_XORI: begin
reg_wdata = op1_i ^ op2_i;
end
`INST_ORI: begin
reg_wdata = op1_i | op2_i;
end
`INST_ANDI: begin
reg_wdata = op1_i & op2_i;
end
`INST_SLLI: begin
reg_wdata = reg1_rdata_i << inst_i[24:20];
end
`INST_SRI: begin
if (inst_i[30] == 1'b1) begin
reg_wdata = (sri_shift & sri_shift_mask) | ({32{reg1_rdata_i[31]}} & (~sri_shift_mask));
end else begin
reg_wdata = reg1_rdata_i >> inst_i[24:20];
end
end
default: begin
reg_wdata = `ZeroWord;
end
endcase
end
...
对于addi指令,添加
wire[31:0] op1_add_op2_res;
assign op1_add_op2_res = op1_i + op2_i;
对于stli指令,添加
wire op1_ge_op2_signed;
assign op1_ge_op2_signed = $signed(op1_i) >= $signed(op2_i);
对于stliu指令,添加
wire op1_ge_op2_unsigned;
assign op1_ge_op2_unsigned = op1_i >= op2_i;
对于rsi指令,添加
wire[31:0] sri_shift;
wire[31:0] sri_shift_mask;
assign sri_shift = reg1_rdata_i >> inst_i[24:20];
assign sri_shift_mask = 32'hffffffff >> inst_i[24:20];
R类型指令有ADD、SUB、SLT、SLTU、AND、OR、XOR、SLL、SRL、SRA指令
// R and M type inst
`define INST_TYPE_R 7'b0110011
// R type inst
`define INST_ADD_SUB 3'b000
`define INST_SLL 3'b001
`define INST_SLT 3'b010
`define INST_SLTU 3'b011
`define INST_XOR 3'b100
`define INST_SR 3'b101
`define INST_OR 3'b110
`define INST_AND 3'b111
`INST_TYPE_R: begin
if ((funct7 == 7'b0000000) || (funct7 == 7'b0100000)) begin
case (funct3)
`INST_ADD_SUB, `INST_SLL, `INST_SLT, `INST_SLTU, `INST_XOR, `INST_SR, `INST_OR, `INST_AND: begin
reg_we_o = `WriteEnable;
reg_waddr_o = rd;
reg1_raddr_o = rs1;
reg2_raddr_o = rs2;
op1_o = reg1_rdata_i;
op2_o = reg2_rdata_i;
end
default: begin
reg_we_o = `WriteDisable;
reg_waddr_o = `ZeroReg;
reg1_raddr_o = `ZeroReg;
reg2_raddr_o = `ZeroReg;
end
endcase
end else begin
reg_we_o = `WriteDisable;
reg_waddr_o = `ZeroReg;
reg1_raddr_o = `ZeroReg;
reg2_raddr_o = `ZeroReg;
end
end
`INST_TYPE_R: begin
if ((funct7 == 7'b0000000) || (funct7 == 7'b0100000)) begin
case (funct3)
`INST_ADD_SUB: begin
if (inst_i[30] == 1'b0) begin
reg_wdata = op1_add_op2_res;
end else begin
reg_wdata = op1_i - op2_i;
end
end
`INST_SLL: begin
reg_wdata = op1_i << op2_i[4:0];
end
`INST_SLT: begin
reg_wdata = {32{(~op1_ge_op2_signed)}} & 32'h1;
end
`INST_SLTU: begin
reg_wdata = {32{(~op1_ge_op2_unsigned)}} & 32'h1;
end
`INST_XOR: begin
reg_wdata = op1_i ^ op2_i;
end
`INST_SR: begin
if (inst_i[30] == 1'b1) begin
reg_wdata = (sr_shift & sr_shift_mask) | ({32{reg1_rdata_i[31]}} & (~sr_shift_mask));
end else begin
reg_wdata = reg1_rdata_i >> reg2_rdata_i[4:0];
end
end
`INST_OR: begin
reg_wdata = op1_i | op2_i;
end
`INST_AND: begin
reg_wdata = op1_i & op2_i;
end
default: begin
reg_wdata = `ZeroWord;
end
endcase
end else begin
reg_wdata = `ZeroWord;
end
end
LW、LH、LHU、LB、LBU、SW、SH、SB指令
lw rd, offset[11:0] (rs1)
// L type inst
`define INST_TYPE_L 7'b0000011
`define INST_LB 3'b000
`define INST_LH 3'b001
`define INST_LW 3'b010
`define INST_LBU 3'b100
`define INST_LHU 3'b101
// S type inst
`define INST_TYPE_S 7'b0100011
`define INST_SB 3'b000
`define INST_SH 3'b001
`define INST_SW 3'b010
`INST_TYPE_L: begin
case (funct3)
`INST_LB, `INST_LH, `INST_LW, `INST_LBU, `INST_LHU: begin
reg1_raddr_o = rs1;
reg2_raddr_o = `ZeroReg;
reg_we_o = `WriteEnable;
reg_waddr_o = rd;
op1_o = reg1_rdata_i;
op2_o = {{20{inst_i[31]}}, inst_i[31:20]};
end
default: begin
reg1_raddr_o = `ZeroReg;
reg2_raddr_o = `ZeroReg;
reg_we_o = `WriteDisable;
reg_waddr_o = `ZeroReg;
end
endcase
end
`INST_TYPE_S: begin
case (funct3)
`INST_SB, `INST_SW, `INST_SH: begin
reg1_raddr_o = rs1;
reg2_raddr_o = rs2;
reg_we_o = `WriteDisable;
reg_waddr_o = `ZeroReg;
op1_o = reg1_rdata_i;
op2_o = {{20{inst_i[31]}}, inst_i[31:25], inst_i[11:7]};
end
default: begin
reg1_raddr_o = `ZeroReg;
reg2_raddr_o = `ZeroReg;
reg_we_o = `WriteDisable;
reg_waddr_o = `ZeroReg;
end
endcase
end
assign mem_raddr_index = (reg1_rdata_i + {{20{inst_i[31]}}, inst_i[31:20]}) & 2'b11;
assign mem_waddr_index = (reg1_rdata_i + {{20{inst_i[31]}}, inst_i[31:25], inst_i[11:7]}) & 2'b11;
`INST_TYPE_L: begin
case (funct3)
mem_wdata_o = `ZeroWord;
mem_waddr_o = `ZeroWord;
mem_we = `WriteDisable;
mem_req = `RIB_REQ;
`INST_LB: begin
mem_raddr_o = op1_add_op2_res;
case (mem_raddr_index)
2'b00: begin
reg_wdata = {{24{mem_rdata_i[7]}}, mem_rdata_i[7:0]};
end
2'b01: begin
reg_wdata = {{24{mem_rdata_i[15]}}, mem_rdata_i[15:8]};
end
2'b10: begin
reg_wdata = {{24{mem_rdata_i[23]}}, mem_rdata_i[23:16]};
end
default: begin
reg_wdata = {{24{mem_rdata_i[31]}}, mem_rdata_i[31:24]};
end
endcase
end
`INST_LH: begin
mem_raddr_o = op1_add_op2_res;
if (mem_raddr_index == 2'b0) begin
reg_wdata = {{16{mem_rdata_i[15]}}, mem_rdata_i[15:0]};
end else begin
reg_wdata = {{16{mem_rdata_i[31]}}, mem_rdata_i[31:16]};
end
end
`INST_LW: begin
mem_raddr_o = op1_add_op2_res;
reg_wdata = mem_rdata_i;
end
`INST_LBU: begin
mem_raddr_o = op1_add_op2_res;
case (mem_raddr_index)
2'b00: begin
reg_wdata = {24'h0, mem_rdata_i[7:0]};
end
2'b01: begin
reg_wdata = {24'h0, mem_rdata_i[15:8]};
end
2'b10: begin
reg_wdata = {24'h0, mem_rdata_i[23:16]};
end
default: begin
reg_wdata = {24'h0, mem_rdata_i[31:24]};
end
endcase
end
`INST_LHU: begin
mem_raddr_o = op1_add_op2_res;
if (mem_raddr_index == 2'b0) begin
reg_wdata = {16'h0, mem_rdata_i[15:0]};
end else begin
reg_wdata = {16'h0, mem_rdata_i[31:16]};
end
end
default: begin
reg_wdata = `ZeroWord;
end
endcase
end
`INST_TYPE_S: begin
case (funct3)
`INST_SB: begin
reg_wdata = `ZeroWord;
mem_we = `WriteEnable;
mem_req = `RIB_REQ;
mem_waddr_o = op1_add_op2_res;
mem_raddr_o = op1_add_op2_res;
case (mem_waddr_index)
2'b00: begin
mem_wdata_o = {mem_rdata_i[31:8], reg2_rdata_i[7:0]};
end
2'b01: begin
mem_wdata_o = {mem_rdata_i[31:16], reg2_rdata_i[7:0], mem_rdata_i[7:0]};
end
2'b10: begin
mem_wdata_o = {mem_rdata_i[31:24], reg2_rdata_i[7:0], mem_rdata_i[15:0]};
end
default: begin
mem_wdata_o = {reg2_rdata_i[7:0], mem_rdata_i[23:0]};
end
endcase
end
`INST_SH: begin
reg_wdata = `ZeroWord;
mem_we = `WriteEnable;
mem_req = `RIB_REQ;
mem_waddr_o = op1_add_op2_res;
mem_raddr_o = op1_add_op2_res;
if (mem_waddr_index == 2'b00) begin
mem_wdata_o = {mem_rdata_i[31:16], reg2_rdata_i[15:0]};
end else begin
mem_wdata_o = {reg2_rdata_i[15:0], mem_rdata_i[15:0]};
end
end
`INST_SW: begin
reg_wdata = `ZeroWord;
mem_we = `WriteEnable;
mem_req = `RIB_REQ;
mem_waddr_o = op1_add_op2_res;
mem_raddr_o = op1_add_op2_res;
mem_wdata_o = reg2_rdata_i;
end
default: begin
mem_wdata_o = `ZeroWord;
mem_raddr_o = `ZeroWord;
mem_waddr_o = `ZeroWord;
mem_we = `WriteDisable;
reg_wdata = `ZeroWord;
end
endcase
end