Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vCLIC interface and logic #44

Closed
wants to merge 12 commits into from
1 change: 1 addition & 0 deletions common/local/util/ex_trace_item.svh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class ex_trace_item;
riscv::ST_ACCESS_FAULT: this.cause_s = "Store Access Fault";
riscv::ENV_CALL_UMODE: this.cause_s = "Environment Call User Mode";
riscv::ENV_CALL_SMODE: this.cause_s = "Environment Call Supervisor Mode";
riscv::ENV_CALL_VSMODE: this.cause_s = "Environment Call Virtual Supervisor Mode";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this is generally useful for H ext... can we commit this separately so that we can also merge it into upstream H ext?

riscv::ENV_CALL_MMODE: this.cause_s = "Environment Call Machine Mode";
riscv::INSTR_PAGE_FAULT: this.cause_s = "Instruction Page Fault";
riscv::LOAD_PAGE_FAULT: this.cause_s = "Load Page Fault";
Expand Down
7 changes: 5 additions & 2 deletions common/local/util/instr_trace_item.svh
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, seems more related to H ext than to vCLIC

Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ class instr_trace_item;
logic [63:0] result;
logic [riscv::PLEN-1:0] paddr;
string priv_lvl;
logic v;
ariane_pkg::bp_resolve_t bp;

logic [4:0] rs1, rs2, rs3, rd;

// constructor creating a new instruction trace item, e.g.: a single instruction with all relevant information
function new (time simtime, longint unsigned cycle, ariane_pkg::scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] gp_reg_file [32],
logic [63:0] fp_reg_file [32], logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, ariane_pkg::bp_resolve_t bp);
logic [63:0] fp_reg_file [32], logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic v, logic debug_mode, ariane_pkg::bp_resolve_t bp);
this.simtime = simtime;
this.cycle = cycle;
this.pc = sbe.pc;
Expand All @@ -56,6 +57,7 @@ class instr_trace_item;
this.paddr = paddr;
this.bp = bp;
this.priv_lvl = (debug_mode) ? "D" : getPrivLevel(priv_lvl);
this.v = v;
this.rs1 = sbe.rs1[4:0];
this.rs2 = sbe.rs2[4:0];
this.rs3 = instr[31:27];
Expand Down Expand Up @@ -361,9 +363,10 @@ class instr_trace_item;
default: s = this.printMnemonic("INVALID");
endcase

s = $sformatf("%8dns %8d %s %h %h %h %-36s", simtime,
s = $sformatf("%8dns %8d %s V=%d %h %h %h %-36s", simtime,
cycle,
priv_lvl,
v,
sbe.pc,
bp.is_mispredict & bp.valid,
instr,
Expand Down
10 changes: 5 additions & 5 deletions common/local/util/instr_tracer.sv
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for the changes in this file (vCLIC->H)

Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ module instr_tracer (
// check if the write back is valid, if not we need to source the result from the register file
// as the most recent version of this register will be there.
if (tracer_if.pck.we_gpr[i] || tracer_if.pck.we_fpr[i]) begin
printInstr(issue_sbe, issue_commit_instruction, tracer_if.pck.wdata[i], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction);
printInstr(issue_sbe, issue_commit_instruction, tracer_if.pck.wdata[i], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.v, tracer_if.pck.debug_mode, bp_instruction);
end else if (ariane_pkg::is_rd_fpr(commit_instruction.op)) begin
printInstr(issue_sbe, issue_commit_instruction, fp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction);
printInstr(issue_sbe, issue_commit_instruction, fp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.v, tracer_if.pck.debug_mode, bp_instruction);
end else begin
printInstr(issue_sbe, issue_commit_instruction, gp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.debug_mode, bp_instruction);
printInstr(issue_sbe, issue_commit_instruction, gp_reg_file[commit_instruction.rd], address_mapping, tracer_if.pck.priv_lvl, tracer_if.pck.v, tracer_if.pck.debug_mode, bp_instruction);
end
end
end
Expand Down Expand Up @@ -186,8 +186,8 @@ module instr_tracer (
bp = {};
endfunction

function void printInstr(ariane_pkg::scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic debug_mode, ariane_pkg::bp_resolve_t bp);
automatic instr_trace_item iti = new ($time, clk_ticks, sbe, instr, gp_reg_file, fp_reg_file, result, paddr, priv_lvl, debug_mode, bp);
function void printInstr(ariane_pkg::scoreboard_entry_t sbe, logic [31:0] instr, logic [63:0] result, logic [riscv::PLEN-1:0] paddr, riscv::priv_lvl_t priv_lvl, logic v, logic debug_mode, ariane_pkg::bp_resolve_t bp);
automatic instr_trace_item iti = new ($time, clk_ticks, sbe, instr, gp_reg_file, fp_reg_file, result, paddr, priv_lvl, v, debug_mode, bp);
// print instruction to console
automatic string print_instr = iti.printInstr();
if (ariane_pkg::ENABLE_SPIKE_COMMIT_LOG && !debug_mode) begin
Expand Down
3 changes: 2 additions & 1 deletion common/local/util/instr_tracer_if.sv
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here (vCLIC->H)

Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ interface instr_tracer_if (
ariane_pkg::exception_t exception;
// current privilege level
riscv::priv_lvl_t priv_lvl;
logic v;
logic debug_mode;
// the tracer just has a passive interface we do not drive anything with it

//pragma translate_off
clocking pck @(posedge clk);
input rstn, flush_unissued, flush, instruction, fetch_valid, fetch_ack, issue_ack, issue_sbe, waddr,
st_valid, st_paddr, ld_valid, ld_kill, ld_paddr, resolve_branch,
wdata, we_gpr, we_fpr, commit_instr, commit_ack, exception, priv_lvl, debug_mode;
wdata, we_gpr, we_fpr, commit_instr, commit_ack, exception, priv_lvl, v, debug_mode;
endclocking
//pragma translate_on

Expand Down
4 changes: 3 additions & 1 deletion core/acc_dispatcher.sv
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,9 @@ module acc_dispatcher
tval2 : '0,
tinst : '0,
gva : '0,
valid: acc_resp_i.error
valid: acc_resp_i.error,
priv_lvl: riscv::PRIV_LVL_M,
trap_to_v: '0
};
assign acc_fflags_valid_o = acc_resp_i.fflags_valid;
assign acc_fflags_o = acc_resp_i.fflags;
Expand Down
4 changes: 3 additions & 1 deletion core/branch_unit.sv
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ module branch_unit #(
else branch_exception_o.tval = '0;
branch_exception_o.tval2 = {riscv::GPLEN{1'b0}};
branch_exception_o.tinst = {riscv::XLEN{1'b0}};
branch_exception_o.gva = CVA6Cfg.RVH ? v_i : 1'b0;
branch_exception_o.gva = CVA6Cfg.RVH ? v_i : 1'b0;
branch_exception_o.priv_lvl = riscv::PRIV_LVL_M;
branch_exception_o.trap_to_v = 1'b0;
// Only throw instruction address misaligned exception if this is indeed a `taken` conditional branch or
// an unconditional jump
if (branch_valid_i && (target_address[0] || (!CVA6Cfg.RVC && target_address[1])) && jump_taken) begin
Expand Down
6 changes: 4 additions & 2 deletions core/commit_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -335,10 +335,12 @@ module commit_stage
// interrupts are correctly prioritized in the CSR reg file, exceptions are prioritized here
exception_o.valid = 1'b0;
exception_o.cause = '0;
exception_o.tval = '0;
exception_o.tval = '0;
exception_o.tval2 = '0;
exception_o.tinst = '0;
exception_o.gva = 1'b0;
exception_o.gva = 1'b0;
exception_o.priv_lvl = riscv::PRIV_LVL_M;
exception_o.trap_to_v = 1'b0;

// we need a valid instruction in the commit stage
if (commit_instr_i[0].valid) begin
Expand Down
48 changes: 39 additions & 9 deletions core/csr_regfile.sv
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ module csr_regfile
// TO_BE_COMPLETED - CLIC_CTRL
output logic [7:0] sintthresh_o,
// TO_BE_COMPLETED - CLIC_CTRL
output logic [7:0] vsintthresh_o,
// TO_BE_COMPLETED - CLIC_CTRL
output logic clic_irq_ready_o,
// we are in single-step mode - COMMIT_STAGE
output logic single_step_o,
Expand Down Expand Up @@ -258,6 +260,7 @@ module csr_regfile
riscv::xlen_t vsepc_q, vsepc_d;
riscv::xlen_t vscause_q, vscause_d;
riscv::xlen_t vstval_q, vstval_d;
riscv::intthresh_rv_t vsintthresh_q, vsintthresh_d;

riscv::xlen_t dcache_q, dcache_d;
riscv::xlen_t icache_q, icache_d;
Expand Down Expand Up @@ -321,12 +324,14 @@ module csr_regfile
assign mintstatus_o = mintstatus_q;
assign mintthresh_o = mintthresh_q.th;
assign sintthresh_o = sintthresh_q.th;
assign vsintthresh_o = vsintthresh_q.th;
assign clic_irq_ready_o = clic_mode_o & ex_i.valid & ex_i.cause[riscv::XLEN-1];
end else begin : gen_dummy_clic_csr_signals
assign clic_mode_o = 1'b0;
assign mintstatus_o = '0;
assign mintthresh_o = '0;
assign sintthresh_o = '0;
assign vsintthresh_o = '0;
assign clic_irq_ready_o = 1'b0;
end

Expand Down Expand Up @@ -432,7 +437,7 @@ module csr_regfile
else read_access_exception = 1'b1;
riscv::CSR_SIP:
if (CVA6Cfg.RVS)
csr_rdata = clic_mode_o ? '0 : ((CVA6Cfg.RVH) ? mip_q & mideleg_q & ~HS_DELEG_INTERRUPTS : mip_q & mideleg_q);
csr_rdata = clic_mode_o ? '0 : ((CVA6Cfg.RVH) ? mip_q & mideleg_q & ~HIE_MASK : mip_q & mideleg_q);
else read_access_exception = 1'b1;
riscv::CSR_STVEC:
if (CVA6Cfg.RVS)
Expand Down Expand Up @@ -513,10 +518,10 @@ module csr_regfile
if (CVA6Cfg.RVH) csr_rdata = hideleg_q;
else read_access_exception = 1'b1;
riscv::CSR_HIE:
if (CVA6Cfg.RVH) csr_rdata = mie_q & HS_DELEG_INTERRUPTS;
if (CVA6Cfg.RVH) csr_rdata = mie_q & HIE_MASK;
else read_access_exception = 1'b1;
riscv::CSR_HIP:
if (CVA6Cfg.RVH) csr_rdata = mip_q & HS_DELEG_INTERRUPTS;
if (CVA6Cfg.RVH) csr_rdata = mip_q & HIE_MASK;
else read_access_exception = 1'b1;
riscv::CSR_HVIP:
if (CVA6Cfg.RVH) csr_rdata = mip_q & VS_DELEG_INTERRUPTS;
Expand All @@ -531,7 +536,7 @@ module csr_regfile
if (CVA6Cfg.RVH) csr_rdata = htinst_q;
else read_access_exception = 1'b1;
riscv::CSR_HGEIE:
if (CVA6Cfg.RVH) csr_rdata = '0;
if (CVA6Cfg.RVH) csr_rdata = {hgeie_q[riscv::XLEN-1:1], 1'b0};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These also look generally useful for H ext

else read_access_exception = 1'b1;
riscv::CSR_HGEIP:
if (CVA6Cfg.RVH) csr_rdata = '0;
Expand Down Expand Up @@ -948,6 +953,7 @@ module csr_regfile
vscause_d = vscause_q;
vstval_d = vstval_q;
vsatp_d = vsatp_q;
vsintthresh_d = vsintthresh_q;

sepc_d = sepc_q;
scause_d = scause_q;
Expand Down Expand Up @@ -1073,6 +1079,16 @@ module csr_regfile
update_access_exception = 1'b1;
end
end
riscv::CSR_VSINTTHRESH: begin
if (CVA6Cfg.RVH && CVA6Cfg.RVSCLIC) begin
// Writes are legal but ignored in CLINT mode
if (clic_mode_o) begin
vsintthresh_d.th = csr_wdata[7:0];
end
end else begin
update_access_exception = 1'b1;
end
end
alex96295 marked this conversation as resolved.
Show resolved Hide resolved
alex96295 marked this conversation as resolved.
Show resolved Hide resolved
riscv::CSR_VSTVEC: begin
if (CVA6Cfg.RVH) begin
vstvec_d = {csr_wdata[riscv::XLEN-1:2], 1'b0, csr_wdata[0]};
Expand Down Expand Up @@ -1260,15 +1276,15 @@ module csr_regfile
end
riscv::CSR_HIE: begin
if (CVA6Cfg.RVH) begin
mask = HS_DELEG_INTERRUPTS;
mask = HIE_MASK;
mie_d = (mie_q & ~mask) | (csr_wdata & mask);
end else begin
update_access_exception = 1'b1;
end
end
riscv::CSR_HIP: begin
if (CVA6Cfg.RVH) begin
mask = riscv::MIP_VSSIP;
mask = HIE_MASK;
mip_d = (mip_q & ~mask) | (csr_wdata & mask);
end else begin
update_access_exception = 1'b1;
Expand Down Expand Up @@ -1307,6 +1323,8 @@ module csr_regfile
riscv::CSR_HGEIE: begin
if (!CVA6Cfg.RVH) begin
update_access_exception = 1'b1;
end else begin
hgeie_d = {csr_wdata[riscv::XLEN-1:1], 1'b0};
end
end
riscv::CSR_HGATP: begin
Expand Down Expand Up @@ -1740,6 +1758,9 @@ module csr_regfile
trap_to_priv_lvl = (priv_lvl_o == riscv::PRIV_LVL_M) ? riscv::PRIV_LVL_M : riscv::PRIV_LVL_S;
// trap to VS only if it is the currently active mode
trap_to_v = v_q;
end else if (ex_i.cause[riscv::XLEN-1] && clic_mode_o) begin
trap_to_priv_lvl = ex_i.priv_lvl;
trap_to_v = ex_i.trap_to_v;
end
end else begin
if (CVA6Cfg.RVS && (ex_i.cause[riscv::XLEN-1] && mideleg_q[ex_i.cause[$clog2(
Expand All @@ -1750,6 +1771,8 @@ module csr_regfile
// traps never transition from a more-privileged mode to a less privileged mode
// so if we are already in M mode, stay there
trap_to_priv_lvl = (priv_lvl_o == riscv::PRIV_LVL_M) ? riscv::PRIV_LVL_M : riscv::PRIV_LVL_S;
end else if (ex_i.cause[riscv::XLEN-1] && clic_mode_o) begin
trap_to_priv_lvl = ex_i.priv_lvl;
end
end

Expand All @@ -1762,7 +1785,7 @@ module csr_regfile
// this can either be user or supervisor mode
vsstatus_d.spp = priv_lvl_q[0];
// set cause
vscause_d = ex_i.cause[riscv::XLEN-1] ? {ex_i.cause[riscv::XLEN-1:2], 2'b01} : ex_i.cause;
vscause_d = (~clic_mode_o & ex_i.cause[riscv::XLEN-1]) ? {ex_i.cause[riscv::XLEN-1:2], 2'b01} : ex_i.cause;
// set epc
vsepc_d = {{riscv::XLEN - riscv::VLEN{pc_i[riscv::VLEN-1]}}, pc_i};
// set vstval
Expand Down Expand Up @@ -2144,6 +2167,9 @@ module csr_regfile
assign irq_ctrl_o.mie = mie_q;
assign irq_ctrl_o.mip = mip_q;
assign irq_ctrl_o.sie = (CVA6Cfg.RVH && v_q) ? vsstatus_q.sie : mstatus_q.sie;
assign irq_ctrl_o.sgeie = CVA6Cfg.RVH ? mie_q[riscv::IRQ_HS_EXT] : '0;
assign irq_ctrl_o.hgeie = CVA6Cfg.RVH ? hgeie_q : '0;
assign irq_ctrl_o.vgein = CVA6Cfg.RVH ? hstatus_q.vgein : '0;
assign irq_ctrl_o.mideleg = mideleg_q;
assign irq_ctrl_o.hideleg = (CVA6Cfg.RVH) ? hideleg_q : '0;
assign irq_ctrl_o.global_enable = (~debug_mode_q)
Expand Down Expand Up @@ -2234,6 +2260,8 @@ module csr_regfile
{riscv::GPLEN{1'b0}},
{riscv::XLEN{1'b0}},
1'b0,
1'b0,
riscv::PRIV_LVL_M,
1'b0
};
// ----------------------------------
Expand Down Expand Up @@ -2306,12 +2334,12 @@ module csr_regfile
// trap_vector_base instead.
if (ex_i.cause[riscv::XLEN-1] &&
((((CVA6Cfg.RVS || CVA6Cfg.RVU) && trap_to_priv_lvl == riscv::PRIV_LVL_M && mtvec_q[0]) || (!CVA6Cfg.RVS && !CVA6Cfg.RVU && mtvec_q[0]))
|| (CVA6Cfg.RVS && trap_to_priv_lvl == riscv::PRIV_LVL_S && !trap_to_v && stvec_q[0])
|| (CVA6Cfg.RVS && trap_to_priv_lvl == riscv::PRIV_LVL_S && !trap_to_v && stvec_q[0] && !clic_mode_o)
|| (CVA6Cfg.RVSCLIC && clic_mode_o && clic_irq_shv_i))) begin
trap_vector_base_o[7:2] = ex_i.cause[5:0];
end
if (ex_i.cause[riscv::XLEN-1] &&
(CVA6Cfg.RVH && trap_to_priv_lvl == riscv::PRIV_LVL_S && trap_to_v && vstvec_q[0])) begin
(CVA6Cfg.RVH && trap_to_priv_lvl == riscv::PRIV_LVL_S && trap_to_v && vstvec_q[0] && !clic_mode_o)) begin
trap_vector_base_o[7:2] = {ex_i.cause[5:2], 2'b01};
end

Expand Down Expand Up @@ -2477,6 +2505,7 @@ module csr_regfile
vsscratch_q <= {riscv::XLEN{1'b0}};
vstval_q <= {riscv::XLEN{1'b0}};
vsatp_q <= {riscv::XLEN{1'b0}};
vsintthresh_q <= 8'b0;
en_ld_st_g_translation_q <= 1'b0;
end
// timer and counters
Expand Down Expand Up @@ -2562,6 +2591,7 @@ module csr_regfile
vsscratch_q <= vsscratch_d;
vstval_q <= vstval_d;
vsatp_q <= vsatp_d;
vsintthresh_q <= vsintthresh_d;
en_ld_st_g_translation_q <= en_ld_st_g_translation_d;
end
// timer and counters
Expand Down
Loading
Loading