Skip to content
68 changes: 65 additions & 3 deletions rtl/ibex_cs_registers.sv
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@ module ibex_cs_registers import ibex_pkg::*; #(
logic [MHPMCounterNum+3-1:0] mcountinhibit_d, mcountinhibit_q;
logic mcountinhibit_we;

// mcounteren: machine counter enable (controls U-mode counter access)
logic [31:0] mcounteren;
logic [MHPMCounterNum+3-1:0] mcounteren_d, mcounteren_q;
logic mcounteren_we;

// mhpmcounter flops are elaborated below providing only the precise number that is required based
// on MHPMCounterNum/MHPMCounterWidth. This signal connects to the Q output of these flops
// where they exist and is otherwise 0.
Expand Down Expand Up @@ -374,9 +379,7 @@ module ibex_cs_registers import ibex_pkg::*; #(
end

// mcounteren: machine counter enable
CSR_MCOUNTEREN: begin
csr_rdata_int = '0;
end
CSR_MCOUNTEREN: csr_rdata_int = mcounteren;

CSR_MSCRATCH: csr_rdata_int = mscratch_q;

Expand Down Expand Up @@ -504,6 +507,35 @@ module ibex_cs_registers import ibex_pkg::*; #(
csr_rdata_int = mhpmcounter[mhpmcounter_idx][63:32];
end

// Unprivileged Counter/Timers (readable from U-mode subject to mcounteren)
CSR_CYCLE,
CSR_INSTRET,
CSR_HPMCOUNTER3,
CSR_HPMCOUNTER4, CSR_HPMCOUNTER5, CSR_HPMCOUNTER6, CSR_HPMCOUNTER7,
CSR_HPMCOUNTER8, CSR_HPMCOUNTER9, CSR_HPMCOUNTER10, CSR_HPMCOUNTER11,
CSR_HPMCOUNTER12, CSR_HPMCOUNTER13, CSR_HPMCOUNTER14, CSR_HPMCOUNTER15,
CSR_HPMCOUNTER16, CSR_HPMCOUNTER17, CSR_HPMCOUNTER18, CSR_HPMCOUNTER19,
CSR_HPMCOUNTER20, CSR_HPMCOUNTER21, CSR_HPMCOUNTER22, CSR_HPMCOUNTER23,
CSR_HPMCOUNTER24, CSR_HPMCOUNTER25, CSR_HPMCOUNTER26, CSR_HPMCOUNTER27,
CSR_HPMCOUNTER28, CSR_HPMCOUNTER29, CSR_HPMCOUNTER30, CSR_HPMCOUNTER31: begin
csr_rdata_int = mhpmcounter[mhpmcounter_idx][31:0];
Comment thread
gautschimi marked this conversation as resolved.
illegal_csr = (priv_lvl_q == PRIV_LVL_U) && !mcounteren[mhpmcounter_idx];
end

CSR_CYCLEH,
CSR_INSTRETH,
CSR_HPMCOUNTER3H,
CSR_HPMCOUNTER4H, CSR_HPMCOUNTER5H, CSR_HPMCOUNTER6H, CSR_HPMCOUNTER7H,
CSR_HPMCOUNTER8H, CSR_HPMCOUNTER9H, CSR_HPMCOUNTER10H, CSR_HPMCOUNTER11H,
CSR_HPMCOUNTER12H, CSR_HPMCOUNTER13H, CSR_HPMCOUNTER14H, CSR_HPMCOUNTER15H,
CSR_HPMCOUNTER16H, CSR_HPMCOUNTER17H, CSR_HPMCOUNTER18H, CSR_HPMCOUNTER19H,
CSR_HPMCOUNTER20H, CSR_HPMCOUNTER21H, CSR_HPMCOUNTER22H, CSR_HPMCOUNTER23H,
CSR_HPMCOUNTER24H, CSR_HPMCOUNTER25H, CSR_HPMCOUNTER26H, CSR_HPMCOUNTER27H,
CSR_HPMCOUNTER28H, CSR_HPMCOUNTER29H, CSR_HPMCOUNTER30H, CSR_HPMCOUNTER31H: begin
csr_rdata_int = mhpmcounter[mhpmcounter_idx][63:32];
illegal_csr = (priv_lvl_q == PRIV_LVL_U) && !mcounteren[mhpmcounter_idx];
end

// Debug triggers
CSR_TSELECT: begin
csr_rdata_int = tselect_rdata;
Expand Down Expand Up @@ -598,6 +630,7 @@ module ibex_cs_registers import ibex_pkg::*; #(
mstack_cause_d = mcause_q;

mcountinhibit_we = 1'b0;
mcounteren_we = 1'b0;
mhpmcounter_we = '0;
mhpmcounterh_we = '0;

Expand Down Expand Up @@ -675,6 +708,7 @@ module ibex_cs_registers import ibex_pkg::*; #(
CSR_DSCRATCH1: dscratch1_en = 1'b1;

// machine counter/timers
CSR_MCOUNTEREN: mcounteren_we = 1'b1;
CSR_MCOUNTINHIBIT: mcountinhibit_we = 1'b1;

CSR_MCYCLE,
Expand Down Expand Up @@ -1277,6 +1311,15 @@ module ibex_cs_registers import ibex_pkg::*; #(
end
end

always_comb begin : mcounteren_update
if (mcounteren_we == 1'b1) begin
// bit 1 must always be 0 (no time CSR implemented)
mcounteren_d = {csr_wdata_int[MHPMCounterNum+2:2], 1'b0, csr_wdata_int[0]};
end else begin
mcounteren_d = mcounteren_q;
end
end

// event selection (hardwired) & control
always_comb begin : gen_mhpmcounter_incr

Expand Down Expand Up @@ -1434,6 +1477,25 @@ module ibex_cs_registers import ibex_pkg::*; #(
end
end

if (MHPMCounterNum < 29) begin : g_mcounteren_reduced
assign mcounteren = {{29 - MHPMCounterNum{1'b0}}, mcounteren_q};
end else begin : g_mcounteren_full
assign mcounteren = mcounteren_q;
end

ibex_csr #(
.Width (MHPMCounterNum+3),
.ShadowCopy(1'b0),
.ResetValue('0)
) u_mcounteren_csr (
.clk_i (clk_i),
.rst_ni (rst_ni),
.wr_data_i (mcounteren_d),
.wr_en_i (mcounteren_we),
.rd_data_o (mcounteren_q),
.rd_error_o()
);

/////////////////////////////
// Debug trigger registers //
/////////////////////////////
Expand Down
63 changes: 63 additions & 0 deletions rtl/ibex_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,69 @@ package ibex_pkg;
CSR_MHPMCOUNTER29H = 12'hB9D,
CSR_MHPMCOUNTER30H = 12'hB9E,
CSR_MHPMCOUNTER31H = 12'hB9F,
// Unprivileged Counter/Timers (readable from U-mode subject to mcounteren)
CSR_CYCLE = 12'hC00,
CSR_INSTRET = 12'hC02,
CSR_HPMCOUNTER3 = 12'hC03,
CSR_HPMCOUNTER4 = 12'hC04,
CSR_HPMCOUNTER5 = 12'hC05,
CSR_HPMCOUNTER6 = 12'hC06,
CSR_HPMCOUNTER7 = 12'hC07,
CSR_HPMCOUNTER8 = 12'hC08,
CSR_HPMCOUNTER9 = 12'hC09,
CSR_HPMCOUNTER10 = 12'hC0A,
CSR_HPMCOUNTER11 = 12'hC0B,
CSR_HPMCOUNTER12 = 12'hC0C,
CSR_HPMCOUNTER13 = 12'hC0D,
CSR_HPMCOUNTER14 = 12'hC0E,
CSR_HPMCOUNTER15 = 12'hC0F,
CSR_HPMCOUNTER16 = 12'hC10,
CSR_HPMCOUNTER17 = 12'hC11,
CSR_HPMCOUNTER18 = 12'hC12,
CSR_HPMCOUNTER19 = 12'hC13,
CSR_HPMCOUNTER20 = 12'hC14,
CSR_HPMCOUNTER21 = 12'hC15,
CSR_HPMCOUNTER22 = 12'hC16,
CSR_HPMCOUNTER23 = 12'hC17,
CSR_HPMCOUNTER24 = 12'hC18,
CSR_HPMCOUNTER25 = 12'hC19,
CSR_HPMCOUNTER26 = 12'hC1A,
CSR_HPMCOUNTER27 = 12'hC1B,
CSR_HPMCOUNTER28 = 12'hC1C,
CSR_HPMCOUNTER29 = 12'hC1D,
CSR_HPMCOUNTER30 = 12'hC1E,
CSR_HPMCOUNTER31 = 12'hC1F,
CSR_CYCLEH = 12'hC80,
CSR_INSTRETH = 12'hC82,
CSR_HPMCOUNTER3H = 12'hC83,
CSR_HPMCOUNTER4H = 12'hC84,
CSR_HPMCOUNTER5H = 12'hC85,
CSR_HPMCOUNTER6H = 12'hC86,
CSR_HPMCOUNTER7H = 12'hC87,
CSR_HPMCOUNTER8H = 12'hC88,
CSR_HPMCOUNTER9H = 12'hC89,
CSR_HPMCOUNTER10H = 12'hC8A,
CSR_HPMCOUNTER11H = 12'hC8B,
CSR_HPMCOUNTER12H = 12'hC8C,
CSR_HPMCOUNTER13H = 12'hC8D,
CSR_HPMCOUNTER14H = 12'hC8E,
CSR_HPMCOUNTER15H = 12'hC8F,
CSR_HPMCOUNTER16H = 12'hC90,
CSR_HPMCOUNTER17H = 12'hC91,
CSR_HPMCOUNTER18H = 12'hC92,
CSR_HPMCOUNTER19H = 12'hC93,
CSR_HPMCOUNTER20H = 12'hC94,
CSR_HPMCOUNTER21H = 12'hC95,
CSR_HPMCOUNTER22H = 12'hC96,
CSR_HPMCOUNTER23H = 12'hC97,
CSR_HPMCOUNTER24H = 12'hC98,
CSR_HPMCOUNTER25H = 12'hC99,
CSR_HPMCOUNTER26H = 12'hC9A,
CSR_HPMCOUNTER27H = 12'hC9B,
CSR_HPMCOUNTER28H = 12'hC9C,
CSR_HPMCOUNTER29H = 12'hC9D,
CSR_HPMCOUNTER30H = 12'hC9E,
CSR_HPMCOUNTER31H = 12'hC9F,
CSR_CPUCTRLSTS = 12'h7C0,
CSR_SECURESEED = 12'h7C1
} csr_num_e;
Expand Down