@@ -147,11 +147,11 @@ module ibex_core import ibex_pkg::*; #(
147
147
148
148
// CPU Control Signals
149
149
// SEC_CM: FETCH.CTRL.LC_GATED
150
- input fetch_enable_t fetch_enable_i,
150
+ input ibex_mubi_t fetch_enable_i,
151
151
output logic alert_minor_o,
152
152
output logic alert_major_internal_o,
153
153
output logic alert_major_bus_o,
154
- output logic core_busy_o
154
+ output ibex_mubi_t core_busy_o
155
155
);
156
156
157
157
localparam int unsigned PMPNumChan = 3 ;
@@ -368,7 +368,31 @@ module ibex_core import ibex_pkg::*; #(
368
368
369
369
// Before going to sleep, wait for I- and D-side
370
370
// interfaces to finish ongoing operations.
371
- assign core_busy_o = ctrl_busy | if_busy | lsu_busy;
371
+ if (SecureIbex) begin : g_core_busy_secure
372
+ // For secure Ibex, the individual bits of core_busy_o are generated from different copies of
373
+ // the various busy signal.
374
+ localparam int unsigned NumBusySignals = 3 ;
375
+ localparam int unsigned NumBusyBits = $bits (ibex_mubi_t) * NumBusySignals;
376
+ logic [NumBusyBits- 1 : 0 ] busy_bits_buf;
377
+ prim_buf # (
378
+ .Width (NumBusyBits)
379
+ ) u_fetch_enable_buf (
380
+ .in_i ({ $bits (ibex_mubi_t){ ctrl_busy, if_busy, lsu_busy}} ),
381
+ .out_o (busy_bits_buf)
382
+ );
383
+
384
+ // Set core_busy_o to IbexMuBiOn if even a single input is high.
385
+ for (genvar i = 0 ; i < $bits (ibex_mubi_t); i++ ) begin : g_core_busy_bits
386
+ if (IbexMuBiOn[i] == 1'b1 ) begin : g_pos
387
+ assign core_busy_o[i] = | busy_bits_buf[i* NumBusySignals + : NumBusySignals];
388
+ end else begin : g_neg
389
+ assign core_busy_o[i] = ~| busy_bits_buf[i* NumBusySignals + : NumBusySignals];
390
+ end
391
+ end
392
+ end else begin : g_core_busy_non_secure
393
+ // For non secure Ibex, synthesis is allowed to optimize core_busy_o.
394
+ assign core_busy_o = (ctrl_busy || if_busy || lsu_busy) ? IbexMuBiOn : IbexMuBiOff;
395
+ end
372
396
373
397
// ////////////
374
398
// IF stage //
@@ -474,22 +498,21 @@ module ibex_core import ibex_pkg::*; #(
474
498
475
499
// Multi-bit fetch enable used when SecureIbex == 1. When SecureIbex == 0 only use the bottom-bit
476
500
// of fetch_enable_i. Ensure the multi-bit encoding has the bottom bit set for on and unset for
477
- // off so FetchEnableOn/FetchEnableOff can be used without needing to know the value of
478
- // SecureIbex.
479
- `ASSERT_INIT (FetchEnableSecureOnBottomBitSet, FetchEnableOn[0 ] == 1'b1 )
480
- `ASSERT_INIT (FetchEnableSecureOffBottomBitClear, FetchEnableOff[0 ] == 1'b0 )
501
+ // off so IbexMuBiOn/IbexMuBiOff can be used without needing to know the value of SecureIbex.
502
+ `ASSERT_INIT (IbexMuBiSecureOnBottomBitSet, IbexMuBiOn[0 ] == 1'b1 )
503
+ `ASSERT_INIT (IbexMuBiSecureOffBottomBitClear, IbexMuBiOff[0 ] == 1'b0 )
481
504
482
505
// fetch_enable_i can be used to stop the core fetching new instructions
483
506
if (SecureIbex) begin : g_instr_req_gated_secure
484
507
// For secure Ibex fetch_enable_i must be a specific multi-bit pattern to enable instruction
485
508
// fetch
486
509
// SEC_CM: FETCH.CTRL.LC_GATED
487
- assign instr_req_gated = instr_req_int & (fetch_enable_i == FetchEnableOn );
488
- assign instr_exec = fetch_enable_i == FetchEnableOn ;
510
+ assign instr_req_gated = instr_req_int & (fetch_enable_i == IbexMuBiOn );
511
+ assign instr_exec = fetch_enable_i == IbexMuBiOn ;
489
512
end else begin : g_instr_req_gated_non_secure
490
513
// For non secure Ibex only the bottom bit of fetch enable is considered
491
514
logic unused_fetch_enable;
492
- assign unused_fetch_enable = ^ fetch_enable_i[$bits (fetch_enable_t )- 1 : 1 ];
515
+ assign unused_fetch_enable = ^ fetch_enable_i[$bits (ibex_mubi_t )- 1 : 1 ];
493
516
494
517
assign instr_req_gated = instr_req_int & fetch_enable_i[0 ];
495
518
assign instr_exec = fetch_enable_i[0 ];
@@ -931,7 +954,7 @@ module ibex_core import ibex_pkg::*; #(
931
954
932
955
// Keep track of the PC last seen in the ID stage when fetch is disabled
933
956
logic [31 : 0 ] pc_at_fetch_disable;
934
- fetch_enable_t last_fetch_enable;
957
+ ibex_mubi_t last_fetch_enable;
935
958
936
959
always_ff @ (posedge clk_i or negedge rst_ni) begin
937
960
if (! rst_ni) begin
@@ -940,7 +963,7 @@ module ibex_core import ibex_pkg::*; #(
940
963
end else begin
941
964
last_fetch_enable <= fetch_enable_i;
942
965
943
- if ((fetch_enable_i != FetchEnableOn ) && (last_fetch_enable == FetchEnableOn )) begin
966
+ if ((fetch_enable_i != IbexMuBiOn ) && (last_fetch_enable == IbexMuBiOn )) begin
944
967
pc_at_fetch_disable <= pc_id;
945
968
end
946
969
end
@@ -949,7 +972,7 @@ module ibex_core import ibex_pkg::*; #(
949
972
// When fetch is disabled no instructions should be executed. Once fetch is disabled either the
950
973
// ID/EX stage is not valid or the PC of the ID/EX stage must remain as it was at disable. The
951
974
// ID/EX valid should not ressert once it has been cleared.
952
- `ASSERT (NoExecWhenFetchEnableNotOn, fetch_enable_i != FetchEnableOn | =>
975
+ `ASSERT (NoExecWhenFetchEnableNotOn, fetch_enable_i != IbexMuBiOn | =>
953
976
(~ instr_valid_id || (pc_id == pc_at_fetch_disable)) && ~ $rose (instr_valid_id))
954
977
955
978
`endif
0 commit comments