diff --git a/core/csr_regs.sv b/core/csr_regs.sv index f683bba..3804e10 100755 --- a/core/csr_regs.sv +++ b/core/csr_regs.sv @@ -104,7 +104,6 @@ module csr_regs logic machine_write; //Control logic - csr_addr_t csr_addr; logic privilege_exception; logic [XLEN-1:0] selected_csr; @@ -123,27 +122,26 @@ module csr_regs always_comb begin swrite_decoder = 0; - swrite_decoder[csr_addr.sub_addr] = supervisor_write ; + swrite_decoder[csr_inputs.addr.sub_addr] = supervisor_write ; mwrite_decoder = 0; - mwrite_decoder[csr_addr.sub_addr] = machine_write ; + mwrite_decoder[csr_inputs.addr.sub_addr] = machine_write ; end //convert addr into packed struct form - assign csr_addr = csr_inputs.csr_addr; - assign supervisor_write = commit && (csr_addr.rw_bits != CSR_READ_ONLY && csr_addr.privilege == SUPERVISOR_PRIVILEGE); - assign machine_write = commit && (csr_addr.rw_bits != CSR_READ_ONLY && csr_addr.privilege == MACHINE_PRIVILEGE); + assign supervisor_write = commit && (csr_inputs.addr.rw_bits != CSR_READ_ONLY && csr_inputs.addr.privilege == SUPERVISOR_PRIVILEGE); + assign machine_write = commit && (csr_inputs.addr.rw_bits != CSR_READ_ONLY && csr_inputs.addr.privilege == MACHINE_PRIVILEGE); //////////////////////////////////////////////////// //Exception Check - assign privilege_exception = new_request & (csr_addr.privilege > privilege_level); + assign privilege_exception = new_request & (csr_inputs.addr.privilege > privilege_level); assign csr_exception.valid = new_request & (invalid_addr | privilege_exception); always_comb begin - case (csr_inputs.csr_op) - CSR_RW : updated_csr = csr_inputs.rs1; - CSR_RS : updated_csr = selected_csr_r | csr_inputs.rs1; - CSR_RC : updated_csr = selected_csr_r & ~csr_inputs.rs1; - default : updated_csr = csr_inputs.rs1; + case (csr_inputs.op) + CSR_RW : updated_csr = csr_inputs.data; + CSR_RS : updated_csr = selected_csr_r | csr_inputs.data; + CSR_RC : updated_csr = selected_csr_r & ~csr_inputs.data; + default : updated_csr = csr_inputs.data; endcase end @@ -452,9 +450,9 @@ generate if (CONFIG.INCLUDE_M_MODE) begin always_ff @(posedge clk) begin if (scratch_reg_write) - scratch_regs[{csr_addr.privilege, csr_addr.sub_addr[2:0]}] <= updated_csr; + scratch_regs[{csr_inputs.addr.privilege, csr_inputs.addr.sub_addr[2:0]}] <= updated_csr; end - assign scratch_out = scratch_regs[{csr_addr.privilege, csr_addr.sub_addr[2:0]}]; + assign scratch_out = scratch_regs[{csr_inputs.addr.privilege, csr_inputs.addr.sub_addr[2:0]}]; end endgenerate @@ -561,7 +559,7 @@ endgenerate always_comb begin invalid_addr = 0; - case (csr_addr) inside + case (csr_inputs.addr) inside //Machine info MISA : selected_csr = CONFIG.INCLUDE_M_MODE ? misa : 0; MVENDORID : selected_csr = CONFIG.INCLUDE_M_MODE ? mvendorid : 0; diff --git a/core/csr_types.sv b/core/csr_types.sv index 6df8246..9255f0d 100644 --- a/core/csr_types.sv +++ b/core/csr_types.sv @@ -23,7 +23,6 @@ package csr_types; import taiga_config::*; import riscv_types::*; - import taiga_types::*; const logic [1:0] CSR_READ_ONLY = 2'b11; diff --git a/core/decode_and_issue.sv b/core/decode_and_issue.sv index f34d1ed..70e49d6 100755 --- a/core/decode_and_issue.sv +++ b/core/decode_and_issue.sv @@ -497,8 +497,14 @@ module decode_and_issue assign gc_inputs.is_fence = is_fence; assign gc_inputs.is_i_fence = CONFIG.INCLUDE_M_MODE & issue_to[UNIT_IDS.CSR] & is_ifence_r; - assign gc_inputs.rs1 = rf.data[RS1]; - assign gc_inputs.rs2 = rf.data[RS2]; + //CSR support + assign gc_inputs.csr_inputs.addr = issue.instruction[31:20]; + assign gc_inputs.csr_inputs.op = issue.fn3[1:0]; + assign gc_inputs.csr_inputs.data = issue.fn3[2] ? {27'b0, issue.rs_addr[RS1]} : rf.data[RS1]; + assign gc_inputs.csr_inputs.reads = ~((issue.fn3[1:0] == CSR_RW) && (issue.rd_addr == 0)); + assign gc_inputs.csr_inputs.writes = ~((issue.fn3[1:0] == CSR_RC) && (issue.rs_addr[RS1] == 0)); + + assign gc_flush_required = CONFIG.INCLUDE_M_MODE && issue_to[UNIT_IDS.CSR] && potential_flush; //////////////////////////////////////////////////// diff --git a/core/gc_unit.sv b/core/gc_unit.sv index 2e781db..503ac79 100644 --- a/core/gc_unit.sv +++ b/core/gc_unit.sv @@ -144,11 +144,6 @@ module gc_unit logic system_op_or_exception_complete; logic exception_with_rd_complete; - //CSR - logic mret; - logic sret; - logic [XLEN-1:0] wb_csr; - csr_inputs_t csr_inputs; exception_packet_t gc_exception; exception_packet_t gc_exception_r; id_t exception_or_system_id; @@ -159,17 +154,13 @@ module gc_unit logic [31:0] csr_mepc; logic [31:0] csr_sepc; - //Write-back handshaking - logic [2:0] fn3; - logic [6:0] opcode; - logic [4:0] opcode_trim; - - logic [4:0] rs1_addr; - logic [4:0] rs2_addr; - logic [4:0] rd_addr; - gc_inputs_t stage1; + + //CSR logic processing_csr; + logic mret; + logic sret; + logic [XLEN-1:0] wb_csr; logic csr_ready_to_complete; logic csr_ready_to_complete_r; id_t instruction_id; @@ -193,13 +184,6 @@ module gc_unit exception_with_rd_complete <= (ls_exception.valid & ~ls_exception_is_store) | (br_exception.valid & branch_exception_is_jump); end - //Instruction decode - assign opcode = stage1.instruction[6:0]; - assign opcode_trim = opcode[6:2]; - assign fn3 = stage1.instruction[14:12]; - assign rs1_addr = stage1.instruction[19:15]; - assign rd_addr = stage1.instruction[11:7]; - //////////////////////////////////////////////////// //GC Operation assign gc_fetch_flush = branch_flush | gc_fetch_pc_override; @@ -323,16 +307,10 @@ module gc_unit //////////////////////////////////////////////////// //CSR registers - assign csr_inputs.rs1 = fn3[2] ? {27'b0, rs1_addr} : stage1.rs1; - assign csr_inputs.csr_addr = stage1.instruction[31:20]; - assign csr_inputs.csr_op = fn3[1:0]; - assign csr_inputs.rs1_is_zero = (rs1_addr == 0); - assign csr_inputs.rd_is_zero = (rd_addr == 0); - csr_regs # (.CONFIG(CONFIG)) csr_registers ( .clk(clk), .rst(rst), - .csr_inputs(csr_inputs), + .csr_inputs(stage1.csr_inputs), .new_request(stage1.is_csr), .read_regs(csr_ready_to_complete), .commit(csr_ready_to_complete_r), diff --git a/core/riscv_types.sv b/core/riscv_types.sv index 928eeec..7121a09 100644 --- a/core/riscv_types.sv +++ b/core/riscv_types.sv @@ -187,7 +187,7 @@ package riscv_types; DCSR = 12'h7B0, DPC = 12'h7B1, DSCRATCH = 12'h7B2 - } csr_t; + } csr_reg_addr_t; typedef enum logic [2:0] { NONCSR_fn3 = 3'b000, diff --git a/core/taiga_types.sv b/core/taiga_types.sv index 2de98b6..c75882b 100755 --- a/core/taiga_types.sv +++ b/core/taiga_types.sv @@ -23,6 +23,7 @@ package taiga_types; import taiga_config::*; import riscv_types::*; + import csr_types::*; localparam LOG2_RETIRE_PORTS = $clog2(RETIRE_PORTS); localparam LOG2_MAX_IDS = $clog2(MAX_IDS); @@ -172,18 +173,17 @@ package taiga_types; } div_inputs_t; typedef struct packed{ - logic [XLEN-1:0] rs1; - logic [11:0] csr_addr; - logic [1:0] csr_op; - logic rs1_is_zero; - logic rd_is_zero; + csr_addr_t addr; + logic[1:0] op; + logic reads; + logic writes; + logic [XLEN-1:0] data; } csr_inputs_t; typedef struct packed{ logic [31:0] pc; logic [31:0] instruction; - logic [XLEN-1:0] rs1; - logic [XLEN-1:0] rs2; + csr_inputs_t csr_inputs; logic is_csr; logic is_fence; logic is_i_fence;