Skip to content
1 change: 1 addition & 0 deletions dv/formal/check/top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ module top import ibex_pkg::*; #(

// CPU Control Signals
input ibex_mubi_t fetch_enable_i,
input ibex_mubi_t mcounteren_writable_i,
output logic core_sleep_o,
output logic alert_minor_o,
output logic alert_major_internal_o,
Expand Down
1 change: 1 addition & 0 deletions dv/riscv_compliance/rtl/ibex_riscv_compliance.sv
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ module ibex_riscv_compliance (
.double_fault_seen_o ( ),

.fetch_enable_i (ibex_pkg::IbexMuBiOn ),
.mcounteren_writable_i (ibex_pkg::IbexMuBiOn ),
.alert_minor_o ( ),
.alert_major_internal_o ( ),
.alert_major_bus_o ( ),
Expand Down
1 change: 1 addition & 0 deletions dv/uvm/core_ibex/tb/core_ibex_tb_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ module core_ibex_tb_top;
.double_fault_seen_o (dut_if.double_fault_seen ),

.fetch_enable_i (dut_if.fetch_enable ),
.mcounteren_writable_i (ibex_pkg::IbexMuBiOn ),
.alert_minor_o (dut_if.alert_minor ),
.alert_major_internal_o (dut_if.alert_major_internal),
.alert_major_bus_o (dut_if.alert_major_bus ),
Expand Down
1 change: 1 addition & 0 deletions examples/simple_system/rtl/ibex_simple_system.sv
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ module ibex_simple_system (
.double_fault_seen_o (),

.fetch_enable_i (ibex_pkg::IbexMuBiOn),
.mcounteren_writable_i (ibex_pkg::IbexMuBiOn),
.alert_minor_o (),
.alert_major_internal_o (),
.alert_major_bus_o (),
Expand Down
2 changes: 2 additions & 0 deletions rtl/ibex_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ module ibex_core import ibex_pkg::*; #(
// CPU Control Signals
// SEC_CM: FETCH.CTRL.LC_GATED
input ibex_mubi_t fetch_enable_i,
input ibex_mubi_t mcounteren_writable_i,
output logic alert_minor_o,
output logic alert_major_internal_o,
output logic alert_major_bus_o,
Expand Down Expand Up @@ -1135,6 +1136,7 @@ module ibex_core import ibex_pkg::*; #(
.icache_enable_o (icache_enable),
.csr_shadow_err_o (csr_shadow_err),
.ic_scr_key_valid_i (ic_scr_key_valid_i),
.mcounteren_writable_i(mcounteren_writable_i),

.csr_save_if_i (csr_save_if),
.csr_save_id_i (csr_save_id),
Expand Down
69 changes: 66 additions & 3 deletions rtl/ibex_cs_registers.sv
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ module ibex_cs_registers import ibex_pkg::*; #(
output logic icache_enable_o,
output logic csr_shadow_err_o,
input logic ic_scr_key_valid_i,
input ibex_mubi_t mcounteren_writable_i,

// Exception save/restore
input logic csr_save_if_i,
Expand Down Expand Up @@ -258,6 +259,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 +380,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 +508,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 +631,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 +709,7 @@ module ibex_cs_registers import ibex_pkg::*; #(
CSR_DSCRATCH1: dscratch1_en = 1'b1;

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

CSR_MCYCLE,
Expand Down Expand Up @@ -1277,6 +1312,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 +1478,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
40 changes: 22 additions & 18 deletions rtl/ibex_lockstep.sv
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ module ibex_lockstep import ibex_pkg::*; #(
input logic double_fault_seen_i,

input ibex_mubi_t fetch_enable_i,
input ibex_mubi_t mcounteren_writable_i,
output logic alert_minor_o,
output logic alert_major_internal_o,
output logic alert_major_bus_o,
Expand Down Expand Up @@ -247,6 +248,7 @@ module ibex_lockstep import ibex_pkg::*; #(
logic irq_nm;
logic debug_req;
ibex_mubi_t fetch_enable;
ibex_mubi_t mcounteren_writable;
logic ic_scr_key_valid;
} delayed_inputs_t;

Expand Down Expand Up @@ -310,24 +312,25 @@ module ibex_lockstep import ibex_pkg::*; #(
end

// Assign the inputs to the delay structure
assign shadow_inputs_in.instr_gnt = instr_gnt_i;
assign shadow_inputs_in.instr_rvalid = instr_rvalid_i;
assign shadow_inputs_in.instr_rdata = instr_rdata_i;
assign shadow_inputs_in.instr_err = instr_err_i;
assign shadow_inputs_in.data_gnt = data_gnt_i;
assign shadow_inputs_in.data_rvalid = data_rvalid_i;
assign shadow_inputs_in.data_rdata = data_rdata_i;
assign shadow_inputs_in.data_err = data_err_i;
assign shadow_inputs_in.rf_rdata_a = rf_rdata_a_i;
assign shadow_inputs_in.rf_rdata_b = rf_rdata_b_i;
assign shadow_inputs_in.irq_software = irq_software_i;
assign shadow_inputs_in.irq_timer = irq_timer_i;
assign shadow_inputs_in.irq_external = irq_external_i;
assign shadow_inputs_in.irq_fast = irq_fast_i;
assign shadow_inputs_in.irq_nm = irq_nm_i;
assign shadow_inputs_in.debug_req = debug_req_i;
assign shadow_inputs_in.fetch_enable = fetch_enable_i;
assign shadow_inputs_in.ic_scr_key_valid = ic_scr_key_valid_i;
assign shadow_inputs_in.instr_gnt = instr_gnt_i;
assign shadow_inputs_in.instr_rvalid = instr_rvalid_i;
assign shadow_inputs_in.instr_rdata = instr_rdata_i;
assign shadow_inputs_in.instr_err = instr_err_i;
assign shadow_inputs_in.data_gnt = data_gnt_i;
assign shadow_inputs_in.data_rvalid = data_rvalid_i;
assign shadow_inputs_in.data_rdata = data_rdata_i;
assign shadow_inputs_in.data_err = data_err_i;
assign shadow_inputs_in.rf_rdata_a = rf_rdata_a_i;
assign shadow_inputs_in.rf_rdata_b = rf_rdata_b_i;
assign shadow_inputs_in.irq_software = irq_software_i;
assign shadow_inputs_in.irq_timer = irq_timer_i;
assign shadow_inputs_in.irq_external = irq_external_i;
assign shadow_inputs_in.irq_fast = irq_fast_i;
assign shadow_inputs_in.irq_nm = irq_nm_i;
assign shadow_inputs_in.debug_req = debug_req_i;
assign shadow_inputs_in.fetch_enable = fetch_enable_i;
assign shadow_inputs_in.mcounteren_writable = mcounteren_writable_i;
assign shadow_inputs_in.ic_scr_key_valid = ic_scr_key_valid_i;

///////////////////
// Output delays //
Expand Down Expand Up @@ -554,6 +557,7 @@ module ibex_lockstep import ibex_pkg::*; #(
`endif

.fetch_enable_i (shadow_inputs_q[0].fetch_enable),
.mcounteren_writable_i (shadow_inputs_q[0].mcounteren_writable),
.alert_minor_o (shadow_alert_minor),
.alert_major_internal_o (shadow_alert_major_internal),
.alert_major_bus_o (shadow_alert_major_bus),
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
13 changes: 13 additions & 0 deletions rtl/ibex_top.sv
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ module ibex_top import ibex_pkg::*; #(

// CPU Control Signals
input ibex_mubi_t fetch_enable_i,
input ibex_mubi_t mcounteren_writable_i,
output logic alert_minor_o,
output logic alert_major_internal_o,
output logic alert_major_bus_o,
Expand Down Expand Up @@ -244,6 +245,7 @@ module ibex_top import ibex_pkg::*; #(
logic scramble_req_d, scramble_req_q;

ibex_mubi_t fetch_enable_buf;
ibex_mubi_t mcounteren_writable_buf;

/////////////////////
// Main clock gate //
Expand Down Expand Up @@ -296,6 +298,11 @@ module ibex_top import ibex_pkg::*; #(
.out_o(fetch_enable_buf)
);

prim_buf #(.Width($bits(ibex_mubi_t))) u_mcounteren_writable_buf (
Comment thread
gautschimi marked this conversation as resolved.
.in_i (mcounteren_writable_i),
.out_o(mcounteren_writable_buf)
);

// ibex_core takes integrity and data bits together. Combine the separate integrity and data
// inputs here.
assign data_rdata_core[31:0] = data_rdata_i;
Expand Down Expand Up @@ -449,6 +456,7 @@ module ibex_top import ibex_pkg::*; #(
`endif

.fetch_enable_i (fetch_enable_buf),
.mcounteren_writable_i (mcounteren_writable_buf),
.alert_minor_o (core_alert_minor),
.alert_major_internal_o(core_alert_major_internal),
.alert_major_bus_o (core_alert_major_bus),
Expand Down Expand Up @@ -829,6 +837,7 @@ module ibex_top import ibex_pkg::*; #(
crash_dump_o,
double_fault_seen_o,
fetch_enable_i,
mcounteren_writable_i,
core_busy_d
});

Expand Down Expand Up @@ -879,6 +888,7 @@ module ibex_top import ibex_pkg::*; #(
crash_dump_t crash_dump_local;
logic double_fault_seen_local;
ibex_mubi_t fetch_enable_local;
ibex_mubi_t mcounteren_writable_local;

ibex_mubi_t core_busy_local;

Expand Down Expand Up @@ -922,6 +932,7 @@ module ibex_top import ibex_pkg::*; #(
crash_dump_o,
double_fault_seen_o,
fetch_enable_i,
mcounteren_writable_i,
core_busy_d
};

Expand Down Expand Up @@ -965,6 +976,7 @@ module ibex_top import ibex_pkg::*; #(
crash_dump_local,
double_fault_seen_local,
fetch_enable_local,
mcounteren_writable_local,
core_busy_local
} = buf_out;

Expand Down Expand Up @@ -1083,6 +1095,7 @@ module ibex_top import ibex_pkg::*; #(
.double_fault_seen_i (double_fault_seen_local),

.fetch_enable_i (fetch_enable_local),
.mcounteren_writable_i (mcounteren_writable_local),
.alert_minor_o (lockstep_alert_minor_local),
.alert_major_internal_o (lockstep_alert_major_internal_local),
.alert_major_bus_o (lockstep_alert_major_bus_local),
Expand Down
Loading