mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 05:07:21 -04:00
Implement CSR instruction in decoder
This commit is contained in:
parent
b0040c754d
commit
0f80a6d211
4 changed files with 89 additions and 19 deletions
|
@ -86,7 +86,8 @@ package ariane_pkg;
|
|||
logic [63:0] result; // for unfinished instructions this field also holds the immediate
|
||||
logic valid; // is the result valid
|
||||
logic use_imm; // should we use the immediate as operand b?
|
||||
logic use_pc; // set if we need to use the PC as operand A, PC from exception
|
||||
logic use_zimm; // use zimm as operand a
|
||||
logic use_pc; // set if we need to use the PC as operand a, PC from exception
|
||||
exception ex; // exception has occurred
|
||||
logic is_compressed; // signals a compressed instructions, we need this information at the commit stage if
|
||||
// we want jump accordingly e.g.: +4, +2
|
||||
|
|
|
@ -50,6 +50,7 @@ module commit_stage (
|
|||
assign waddr_a_o = commit_instr_i.rd;
|
||||
assign wdata_a_o = commit_instr_i.result;
|
||||
assign pc_o = commit_instr_i.pc;
|
||||
|
||||
// commit instruction
|
||||
// write register file
|
||||
always_comb begin : commit
|
||||
|
|
|
@ -30,7 +30,7 @@ module decoder (
|
|||
} imm_select;
|
||||
|
||||
logic [63:0] imm_i_type;
|
||||
logic [63:0] imm_iz_type;
|
||||
logic [11:0] imm_iz_type;
|
||||
logic [63:0] imm_s_type;
|
||||
logic [63:0] imm_sb_type;
|
||||
logic [63:0] imm_u_type;
|
||||
|
@ -44,26 +44,90 @@ module decoder (
|
|||
|
||||
always_comb begin : decoder
|
||||
|
||||
imm_select = NOIMM;
|
||||
illegal_instr = 1'b0;
|
||||
instruction_o.pc = pc_i;
|
||||
instruction_o.fu = NONE;
|
||||
instruction_o.op = ADD;
|
||||
instruction_o.rs1 = 5'b0;
|
||||
instruction_o.rs2 = 5'b0;
|
||||
instruction_o.rd = 5'b0;
|
||||
instruction_o.use_pc = 1'b0;
|
||||
instruction_o.trans_id = 5'b0;
|
||||
imm_select = NOIMM;
|
||||
illegal_instr = 1'b0;
|
||||
instruction_o.pc = pc_i;
|
||||
instruction_o.fu = NONE;
|
||||
instruction_o.op = ADD;
|
||||
instruction_o.rs1 = 5'b0;
|
||||
instruction_o.rs2 = 5'b0;
|
||||
instruction_o.rd = 5'b0;
|
||||
instruction_o.use_pc = 1'b0;
|
||||
instruction_o.trans_id = 5'b0;
|
||||
instruction_o.is_compressed = is_compressed_i;
|
||||
// TODO end
|
||||
instruction_o.use_zimm = 1'b0;
|
||||
|
||||
if (~ex_i.valid) begin
|
||||
case (instr.rtype.opcode)
|
||||
OPCODE_SYSTEM: begin
|
||||
// TODO: Implement
|
||||
instruction_o.fu = CSR;
|
||||
instruction_o.rs1 = instr.itype.rs1;
|
||||
instruction_o.rd = instr.itype.rd;
|
||||
|
||||
unique case (instr.itype.funct3)
|
||||
3'b000: begin
|
||||
// TODO:
|
||||
// ECALL, EBREAK, SFEBCE.VM
|
||||
// MRET/SRET/URET, WFI
|
||||
illegal_instr = 1'b1;
|
||||
end
|
||||
// atomically swaps values in the CSR and integer register
|
||||
3'b001: begin// CSRRW
|
||||
imm_select = IIMM;
|
||||
instruction_o.op = CSR_WRITE;
|
||||
end
|
||||
// atomically set values in the CSR and write back to rd
|
||||
3'b010: begin// CSRRS
|
||||
imm_select = IIMM;
|
||||
// this is just a read
|
||||
if (instr.itype.rs1 == 5'b0)
|
||||
instruction_o.op = CSR_READ;
|
||||
else
|
||||
instruction_o.op = CSR_SET;
|
||||
end
|
||||
// atomically clear values in the CSR and write back to rd
|
||||
3'b011: begin// CSRRC
|
||||
imm_select = IIMM;
|
||||
// this is just a read
|
||||
if (instr.itype.rs1 == 5'b0)
|
||||
instruction_o.op = CSR_READ;
|
||||
else
|
||||
instruction_o.op = CSR_SET;
|
||||
end
|
||||
// use zimm and iimm
|
||||
3'b101: begin// CSRRWI
|
||||
instruction_o.rs1 = 5'b0;
|
||||
imm_select = IIMM;
|
||||
instruction_o.use_zimm = 1'b1;
|
||||
instruction_o.op = CSR_WRITE;
|
||||
end
|
||||
3'b110: begin// CSRRSI
|
||||
instruction_o.rs1 = 5'b0;
|
||||
imm_select = IIMM;
|
||||
instruction_o.use_zimm = 1'b1;
|
||||
// this is just a read
|
||||
if (instr.itype.rs1 == 5'b0)
|
||||
instruction_o.op = CSR_READ;
|
||||
else
|
||||
instruction_o.op = CSR_SET;
|
||||
end
|
||||
3'b111: begin// CSRRCI
|
||||
instruction_o.rs1 = 5'b0;
|
||||
imm_select = IIMM;
|
||||
instruction_o.use_zimm = 1'b1;
|
||||
// this is just a read
|
||||
if (instr.itype.rs1 == 5'b0)
|
||||
instruction_o.op = CSR_READ;
|
||||
else
|
||||
instruction_o.op = CSR_CLEAR;
|
||||
end
|
||||
default: illegal_instr = 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
||||
OPCODE_FENCE: begin
|
||||
// TODO: Implement
|
||||
// FENCE, FENCE.I,
|
||||
end
|
||||
|
||||
// --------------------------
|
||||
|
@ -269,7 +333,6 @@ module decoder (
|
|||
imm_sb_type = { {51 {instruction_i[31]}}, instruction_i[31], instruction_i[7], instruction_i[30:25], instruction_i[11:8], 1'b0 };
|
||||
imm_u_type = { {32 {instruction_i[31]}}, instruction_i[31:12], 12'b0 }; // JAL, AUIPC, sign extended to 64 bit
|
||||
imm_uj_type = { {44 {instruction_i[31]}}, instruction_i[19:12], instruction_i[20], instruction_i[30:21], 1'b0 };
|
||||
// imm_z_type = { 59'b0, instruction_i[`REG_S1] };
|
||||
imm_s2_type = { 59'b0, instruction_i[24:20] };
|
||||
imm_bi_type = { {59{instruction_i[24]}}, instruction_i[24:20] };
|
||||
imm_s3_type = { 59'b0, instruction_i[29:25] };
|
||||
|
|
|
@ -61,7 +61,7 @@ module issue_read_operands (
|
|||
input logic [63:0] wdata_a_i,
|
||||
input logic we_a_i
|
||||
);
|
||||
logic stall; // stall signal, we do not want to fetch any more entries
|
||||
logic stall; // stall signal, we do not want to fetch any more entries
|
||||
logic fu_busy; // functional unit is busy
|
||||
logic [63:0] operand_a_regfile, operand_b_regfile; // operands coming from regfile
|
||||
|
||||
|
@ -146,9 +146,11 @@ module issue_read_operands (
|
|||
// poll the scoreboard for those values
|
||||
rs1_o = issue_instr_i.rs1;
|
||||
rs2_o = issue_instr_i.rs2;
|
||||
// 0. check that we are not using the zimm type in rs1
|
||||
// as this is an immediate we do not have to wait on anything here
|
||||
// 1. check if the source registers are clobberd
|
||||
// 2. poll the scoreboard
|
||||
if (rd_clobber_i[issue_instr_i.rs1] != NONE) begin
|
||||
if (~issue_instr_i.use_zimm && rd_clobber_i[issue_instr_i.rs1] != NONE) begin
|
||||
// the operand is available, forward it
|
||||
if (rs1_valid_i)
|
||||
forward_rs1 = 1'b1;
|
||||
|
@ -164,8 +166,6 @@ module issue_read_operands (
|
|||
else // the operand is not available -> stall
|
||||
stall = 1'b1;
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
// Forwarding/Output MUX
|
||||
always_comb begin : forwarding
|
||||
|
@ -187,6 +187,11 @@ module issue_read_operands (
|
|||
operand_a_n = issue_instr_i.pc;
|
||||
end
|
||||
|
||||
// use the zimm as operand a
|
||||
if (issue_instr_i.use_zimm) begin
|
||||
// zero extend operand a
|
||||
operand_a_n = {52'b0, issue_instr_i.rs1};
|
||||
end
|
||||
// or is it an immediate (including PC), this is not the case for a store
|
||||
if (issue_instr_i.use_imm && issue_instr_i.op != SD
|
||||
&& issue_instr_i.op != SW
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue