Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci/vars.env
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
# Quote values to ensure they are parsed as string (version numbers might
# end up as float otherwise).
VERILATOR_VERSION=v4.210
IBEX_COSIM_VERSION=6d5b660
IBEX_COSIM_VERSION=aadf648

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This bump adds ZIHPM extension to Spike but it also pulls in the Zc* extensions. Is there any risk in that inclusion?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right. But that will be fine, because we anyway already have the Zc* extension in the RTL. Only the DV is not fully merged yet, but already having Spike support those extensions will not hurt.

RISCV_TOOLCHAIN_TAR_VERSION=20220210-1
RISCV_TOOLCHAIN_TAR_VARIANT=lowrisc-toolchain-gcc-rv32imcb
RISCV_COMPLIANCE_GIT_VERSION=844c6660ef3f0d9b96957991109dfd80cc4938e2
Expand Down
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,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What's the point of making this an input as opposed to a parameter? Is there a use-case to be able to switch this dynamically during runtime?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes. This allows locking the mcounteren in a certain configuration. For example, the boot code could enable only the instret counter to be accessible to the user mode and then lock it to prevent the software from switching it later and use other counters to profile the core. This option, gives us the most flexibility and security.

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It probably makes sense to have at least a local parameter with the 3 offset since this is shared with the mcountinhibit above.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I double checked this mapping and I think they are right.

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