CSR/GC restructuring

This commit is contained in:
Eric Matthews 2021-10-26 10:37:40 -07:00
parent e56790a442
commit 2b547bc0d5
6 changed files with 92 additions and 66 deletions

View file

@ -35,11 +35,15 @@ module csr_regs
input logic clk,
input logic rst,
//GC unit
//Unit Interfaces
input csr_inputs_t csr_inputs,
input new_request,
input read_regs,
input commit,
input logic new_request,
input id_t id,
unit_writeback_interface.unit wb,
input logic gc_issue_hold,
input logic commit,
input exception_packet_t gc_exception,
output exception_packet_t csr_exception,
output logic [1:0] current_privilege,
@ -74,7 +78,8 @@ module csr_regs
(* ramstyle = "MLAB, no_rw_check" *) logic[XLEN-1:0] scratch_regs [31:0];//Only 0x1 and 0x3 used by supervisor and machine mode respectively
logic[XLEN-1:0] scratch_out;
csr_inputs_t csr_inputs_r;
privilege_t privilege_level;
privilege_t next_privilege_level;
@ -116,32 +121,43 @@ module csr_regs
logic done;
logic [255:0] swrite_decoder;
logic [255:0] swrite_en;
logic [255:0] mwrite_decoder;
logic [255:0] mwrite_en;
////////////////////////////////////////////////////
//Implementation
always_ff @(posedge clk) begin
if (new_request) begin
csr_inputs_r <= csr_inputs;
end
end
assign supervisor_write = commit && (csr_inputs_r.addr.rw_bits != CSR_READ_ONLY && csr_inputs_r.addr.privilege == SUPERVISOR_PRIVILEGE);
assign machine_write = commit && (csr_inputs_r.addr.rw_bits != CSR_READ_ONLY && csr_inputs_r.addr.privilege == MACHINE_PRIVILEGE);
always_comb begin
swrite_decoder = 0;
swrite_decoder[csr_inputs.addr.sub_addr] = supervisor_write ;
swrite_decoder[csr_inputs_r.addr.sub_addr] = supervisor_write ;
mwrite_decoder = 0;
mwrite_decoder[csr_inputs.addr.sub_addr] = machine_write ;
mwrite_decoder[csr_inputs_r.addr.sub_addr] = machine_write ;
end
//convert addr into packed struct form
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);
always_ff @(posedge clk) begin
swrite_en <= swrite_decoder;
mwrite_en <= mwrite_decoder;
end
////////////////////////////////////////////////////
//Exception Check
assign privilege_exception = new_request & (csr_inputs.addr.privilege > privilege_level);
assign csr_exception.valid = new_request & (invalid_addr | privilege_exception);
assign privilege_exception = csr_inputs_r.addr.privilege > privilege_level;
assign csr_exception.valid = commit & (invalid_addr | privilege_exception);
always_comb begin
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;
case (csr_inputs_r.op)
CSR_RW : updated_csr = csr_inputs_r.data;
CSR_RS : updated_csr = selected_csr_r | csr_inputs_r.data;
CSR_RC : updated_csr = selected_csr_r & ~csr_inputs_r.data;
default : updated_csr = csr_inputs_r.data;
endcase
end
@ -274,10 +290,10 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
end
mstatus_t mstatus_write_mask;
assign mstatus_write_mask = machine_write ? mstatus_mask : sstatus_mask;
assign mstatus_write_mask = mwrite_en[MSTATUS[7:0]] ? mstatus_mask : sstatus_mask;
always_comb begin
if (mwrite_decoder[MSTATUS[7:0]] | swrite_decoder[SSTATUS[7:0]])
if (mwrite_en[MSTATUS[7:0]] | swrite_en[SSTATUS[7:0]])
mstatus_new = (mstatus & ~mstatus_write_mask) | (updated_csr & mstatus_write_mask);
else if (interrupt | gc_exception.valid)
mstatus_new = mstatus_exception;
@ -299,7 +315,7 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
//No vectored mode, mode hard-coded to zero
always_ff @(posedge clk) begin
mtvec[1:0] <= '0;
if (mwrite_decoder[MTVEC[7:0]])
if (mwrite_en[MTVEC[7:0]])
mtvec[XLEN-1:2] <= updated_csr[XLEN-1:2];
end
assign trap_pc = mtvec;
@ -328,7 +344,7 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
always_ff @(posedge clk) begin
if (rst)
medeleg <= '0;
else if (mwrite_decoder[MEDELEG[7:0]])
else if (mwrite_en[MEDELEG[7:0]])
medeleg <= (updated_csr & medeleg_mask);
end
@ -346,7 +362,7 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
always_ff @(posedge clk) begin
if (rst)
mideleg <= '0;
else if (mwrite_decoder[MIDELEG[7:0]])
else if (mwrite_en[MIDELEG[7:0]])
mideleg <= (updated_csr & mideleg_mask);
end
@ -356,7 +372,7 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
always_ff @(posedge clk) begin
if (rst)
mip <= 0;
else if (mwrite_decoder[MIP[7:0]])
else if (mwrite_en[MIP[7:0]])
mip <= (updated_csr & mip_mask);
end
@ -368,9 +384,9 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
always_ff @(posedge clk) begin
if (rst)
mie_reg <= '0;
else if (mwrite_decoder[MIE[7:0]])
else if (mwrite_en[MIE[7:0]])
mie_reg <= (updated_csr & mie_mask);
else if (swrite_decoder[SIE[7:0]])
else if (swrite_en[SIE[7:0]])
mie_reg <= (updated_csr & sie_mask);
end
@ -380,7 +396,7 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
//exception causing PC. Lower two bits tied to zero.
always_ff @(posedge clk) begin
mepc[1:0] <= '0;
if (mwrite_decoder[MEPC[7:0]] | gc_exception.valid)
if (mwrite_en[MEPC[7:0]] | gc_exception.valid)
mepc[XLEN-1:2] <= gc_exception.valid ? exception_pc[XLEN-1:2] : updated_csr[XLEN-1:2];
end
assign csr_mepc = mepc;
@ -429,7 +445,7 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
always_ff @(posedge clk) begin
mcause.zeroes <= '0;
if ((mcause_write_valid & mwrite_decoder[MCAUSE[7:0]]) | gc_exception.valid) begin
if ((mcause_write_valid & mwrite_en[MCAUSE[7:0]]) | gc_exception.valid) begin
mcause.interrupt <= gc_exception.valid ? 1'b0 : updated_csr[XLEN-1];
mcause.code <= gc_exception.valid ? gc_exception.code : updated_csr[ECODE_W-1:0];
end
@ -438,7 +454,7 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
////////////////////////////////////////////////////
//MTVAL
always_ff @(posedge clk) begin
if (mwrite_decoder[MTVAL[7:0]] | gc_exception.valid)
if (mwrite_en[MTVAL[7:0]] | gc_exception.valid)
mtval <= gc_exception.valid ? gc_exception.tval : updated_csr;
end
@ -446,13 +462,13 @@ generate if (CONFIG.INCLUDE_M_MODE) begin
//Scratch regs
//For efficient LUT-RAM packing, all scratch regs are stored together
logic scratch_reg_write;
assign scratch_reg_write = mwrite_decoder[MSCRATCH[7:0]] | swrite_decoder[SSCRATCH[7:0]];
assign scratch_reg_write = mwrite_en[MSCRATCH[7:0]] | swrite_en[SSCRATCH[7:0]];
always_ff @(posedge clk) begin
if (scratch_reg_write)
scratch_regs[{csr_inputs.addr.privilege, csr_inputs.addr.sub_addr[2:0]}] <= updated_csr;
scratch_regs[{csr_inputs_r.addr.privilege, csr_inputs_r.addr.sub_addr[2:0]}] <= updated_csr;
end
assign scratch_out = scratch_regs[{csr_inputs.addr.privilege, csr_inputs.addr.sub_addr[2:0]}];
assign scratch_out = scratch_regs[{csr_inputs_r.addr.privilege, csr_inputs_r.addr.sub_addr[2:0]}];
end
endgenerate
@ -501,7 +517,7 @@ generate if (CONFIG.INCLUDE_S_MODE) begin
always_ff @(posedge clk) begin
if (rst)
stvec <= {CONFIG.CSRS.RESET_VEC[XLEN-1:2], 2'b00};
else if (swrite_decoder[STVEC[7:0]])
else if (swrite_en[STVEC[7:0]])
stvec <= (updated_csr & stvec_mask);
end
@ -512,7 +528,7 @@ generate if (CONFIG.INCLUDE_S_MODE) begin
always_ff @(posedge clk) begin
if (rst)
satp <= 0;
else if (swrite_decoder[SATP[7:0]])
else if (swrite_en[SATP[7:0]])
satp <= (updated_csr & satp_mask);
end
@ -531,10 +547,10 @@ endgenerate
logic[CONFIG.CSRS.COUNTER_W-1:0] mcycle_input_next;
logic mcycle_inc;
assign mcycle_input_next[31:0] = mwrite_decoder[MCYCLE[7:0]] ? updated_csr : mcycle[31:0];
assign mcycle_input_next[CONFIG.CSRS.COUNTER_W-1:32] = mwrite_decoder[MCYCLEH[7:0]] ? updated_csr[CONFIG.CSRS.COUNTER_W-33:0] : mcycle[CONFIG.CSRS.COUNTER_W-1:32];
assign mcycle_input_next[31:0] = mwrite_en[MCYCLE[7:0]] ? updated_csr : mcycle[31:0];
assign mcycle_input_next[CONFIG.CSRS.COUNTER_W-1:32] = mwrite_en[MCYCLEH[7:0]] ? updated_csr[CONFIG.CSRS.COUNTER_W-33:0] : mcycle[CONFIG.CSRS.COUNTER_W-1:32];
assign mcycle_inc = ~(mwrite_decoder[MCYCLE[7:0]] | mwrite_decoder[MCYCLEH[7:0]]);
assign mcycle_inc = ~(mwrite_en[MCYCLE[7:0]] | mwrite_en[MCYCLEH[7:0]]);
always_ff @(posedge clk) begin
if (rst)
@ -545,10 +561,10 @@ endgenerate
logic[CONFIG.CSRS.COUNTER_W-1:0] minst_ret_input_next;
logic[LOG2_RETIRE_PORTS:0] minst_ret_inc;
assign minst_ret_input_next[31:0] = mwrite_decoder[MINSTRET[7:0]] ? updated_csr : minst_ret[31:0];
assign minst_ret_input_next[CONFIG.CSRS.COUNTER_W-1:32] = mwrite_decoder[MINSTRETH[7:0]] ? updated_csr[CONFIG.CSRS.COUNTER_W-33:0] : minst_ret[CONFIG.CSRS.COUNTER_W-1:32];
assign minst_ret_input_next[31:0] = mwrite_en[MINSTRET[7:0]] ? updated_csr : minst_ret[31:0];
assign minst_ret_input_next[CONFIG.CSRS.COUNTER_W-1:32] = mwrite_en[MINSTRETH[7:0]] ? updated_csr[CONFIG.CSRS.COUNTER_W-33:0] : minst_ret[CONFIG.CSRS.COUNTER_W-1:32];
assign minst_ret_inc = {(LOG2_RETIRE_PORTS+1){~(mwrite_decoder[MINSTRET[7:0]] | mwrite_decoder[MINSTRETH[7:0]])}} & retire.count;
assign minst_ret_inc = {(LOG2_RETIRE_PORTS+1){~(mwrite_en[MINSTRET[7:0]] | mwrite_en[MINSTRETH[7:0]])}} & retire.count;
always_ff @(posedge clk) begin
if (rst)
@ -557,9 +573,12 @@ endgenerate
minst_ret <= minst_ret_input_next + CONFIG.CSRS.COUNTER_W'(minst_ret_inc);
end
////////////////////////////////////////////////////
//CSR mux
always_comb begin
invalid_addr = 0;
case (csr_inputs.addr) inside
case (csr_inputs_r.addr) inside
//Machine info
MISA : selected_csr = CONFIG.INCLUDE_M_MODE ? misa : 0;
MVENDORID : selected_csr = CONFIG.INCLUDE_M_MODE ? mvendorid : 0;
@ -626,10 +645,24 @@ endgenerate
endcase
end
always_ff @(posedge clk) begin
if (read_regs)
if (commit)
selected_csr_r <= selected_csr;
end
assign wb_csr = selected_csr_r;
////////////////////////////////////////////////////
//Output
always_ff @(posedge clk) begin
if (new_request)
wb.id <= id;
end
always_ff @(posedge clk) begin
if (rst)
wb.done <= 0;
else
wb.done <= commit;
end
assign wb.rd = selected_csr_r;
endmodule

View file

@ -58,6 +58,7 @@ module decode_and_issue
output load_store_inputs_t ls_inputs,
output branch_inputs_t branch_inputs,
output gc_inputs_t gc_inputs,
output csr_inputs_t csr_inputs,
output mul_inputs_t mul_inputs,
output div_inputs_t div_inputs,
@ -498,11 +499,11 @@ module decode_and_issue
assign gc_inputs.is_i_fence = CONFIG.INCLUDE_M_MODE & issue_to[UNIT_IDS.CSR] & is_ifence_r;
//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 csr_inputs.addr = issue.instruction[31:20];
assign csr_inputs.op = issue.fn3[1:0];
assign csr_inputs.data = issue.fn3[2] ? {27'b0, issue.rs_addr[RS1]} : rf.data[RS1];
assign csr_inputs.reads = ~((issue.fn3[1:0] == CSR_RW) && (issue.rd_addr == 0));
assign 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;

View file

@ -39,6 +39,7 @@ module gc_unit
//Decode
unit_issue_interface.unit issue,
input gc_inputs_t gc_inputs,
input csr_inputs_t csr_inputs,
input logic gc_flush_required,
//Branch miss predict
input logic branch_flush,
@ -310,10 +311,12 @@ module gc_unit
csr_regs # (.CONFIG(CONFIG))
csr_registers (
.clk(clk), .rst(rst),
.csr_inputs(stage1.csr_inputs),
.new_request(stage1.is_csr),
.read_regs(csr_ready_to_complete),
.commit(csr_ready_to_complete_r),
.csr_inputs(csr_inputs),
.new_request(issue.possible_issue & gc_inputs.is_csr & ~gc_issue_hold),
.id(issue.id),
.wb(wb),
.gc_issue_hold(gc_issue_hold),
.commit(csr_ready_to_complete),
.gc_exception(gc_exception_r),
.csr_exception(csr_exception),
.current_privilege(current_privilege),
@ -355,19 +358,6 @@ module gc_unit
csr_ready_to_complete_r <= csr_ready_to_complete;
end
always_ff @(posedge clk) begin
csr_id <= instruction_id;
if (issue.new_request) begin
instruction_id <= issue.id;
end
end
////////////////////////////////////////////////////
//Output
assign wb.rd = wb_csr;
assign wb.done = csr_ready_to_complete_r;
assign wb.id = csr_id;
////////////////////////////////////////////////////
//End of Implementation
////////////////////////////////////////////////////

View file

@ -111,6 +111,7 @@ module taiga
mul_inputs_t mul_inputs;
div_inputs_t div_inputs;
gc_inputs_t gc_inputs;
csr_inputs_t csr_inputs;
unit_issue_interface unit_issue [NUM_UNITS-1:0]();
@ -391,6 +392,7 @@ module taiga
.ls_inputs (ls_inputs),
.branch_inputs (branch_inputs),
.gc_inputs (gc_inputs),
.csr_inputs (csr_inputs),
.mul_inputs (mul_inputs),
.div_inputs (div_inputs),
.unit_issue (unit_issue),
@ -524,6 +526,7 @@ module taiga
.rst (rst),
.issue (unit_issue[UNIT_IDS.CSR]),
.gc_inputs (gc_inputs),
.csr_inputs (csr_inputs),
.gc_flush_required (gc_flush_required),
.branch_flush (branch_flush),
.potential_branch_exception (potential_branch_exception),

View file

@ -183,7 +183,6 @@ package taiga_types;
typedef struct packed{
logic [31:0] pc;
logic [31:0] instruction;
csr_inputs_t csr_inputs;
logic is_csr;
logic is_fence;
logic is_i_fence;

View file

@ -1,5 +1,6 @@
core/taiga_config.sv
core/riscv_types.sv
core/csr_types.sv
core/taiga_types.sv
l2_arbiter/l2_config_and_types.sv
l2_arbiter/l2_interfaces.sv
@ -10,7 +11,6 @@ local_memory/local_mem.sv
core/interfaces.sv
core/external_interfaces.sv
core/csr_types.sv
core/csr_regs.sv
core/gc_unit.sv