[dv/alert_handler] randomly enable and drive alerts
In sanity test, this change support randomly enable and drive all the
alert sources. Then scb will predict the alert_cause and interrupt
accordingly.
Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv b/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
index 2a21e26..32118d1 100644
--- a/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
+++ b/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
@@ -39,28 +39,30 @@
endtask
virtual task process_alert_fifo();
- uvm_reg_field list_of_alert_cause_fields[$];
- uvm_reg_field list_of_intr_state_fields[$];
- ral.alert_cause.get_fields(list_of_alert_cause_fields);
- ral.intr_state.get_fields(list_of_intr_state_fields);
+ uvm_reg_field alert_cause_fields[$];
+ uvm_reg_field intr_state_fields[$];
+ ral.alert_cause.get_fields(alert_cause_fields);
+ ral.intr_state.get_fields(intr_state_fields);
foreach (alert_fifo[i]) begin
+ automatic int index = i;
fork
- automatic int index = i;
- alert_seq_item act_item;
forever begin
+ alert_seq_item act_item;
alert_fifo[index].get(act_item);
// once the alert is received
if (act_item.alert_esc_type == AlertEscSigTrans && !act_item.timeout &&
act_item.alert_handshake_sta == AlertReceived) begin
uvm_reg_field alert_cause_field, intr_state_field;
- bit [TL_DW-1:0] intr_class;
+ bit [TL_DW-1:0] alert_en = ral.alert_en.get_mirrored_value();
- alert_cause_field = list_of_alert_cause_fields[index];
- intr_class = ral.alert_class.get_mirrored_value();
- intr_state_field =
- list_of_intr_state_fields[intr_class << (TL_DW-2*index) >> (TL_DW-2)];
- void'(alert_cause_field.predict(1));
- void'(intr_state_field.predict(1));
+ if (alert_en[index]) begin
+ bit [TL_DW-1:0] intr_class = ral.alert_class.get_mirrored_value();
+ alert_cause_field = alert_cause_fields[index];
+ // extract the two bits that indicates which intr class this alert will trigger
+ intr_state_field = intr_state_fields[(intr_class >> index*2) & 'b11];
+ void'(alert_cause_field.predict(1));
+ void'(intr_state_field.predict(1));
+ end
end
end
join_none
@@ -69,10 +71,10 @@
virtual task process_esc_fifo();
foreach (esc_fifo[i]) begin
+ automatic int index = i;
fork
- automatic int index = i;
- alert_seq_item act_item;
forever begin
+ alert_seq_item act_item;
esc_fifo[index].get(act_item);
end
join_none
diff --git a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_base_vseq.sv b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_base_vseq.sv
index fcbd854..f219b72 100644
--- a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_base_vseq.sv
+++ b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_base_vseq.sv
@@ -25,9 +25,10 @@
endtask
// setup basic alert_handler features
+ // alert_class default 0 -> all alert will trigger interrupt classA
virtual task alert_handler_init(bit [NUM_ALERT_HANDLER_CLASSES-1:0] intr_en = '1,
- bit alert_en = 1'b1,
- bit [TL_DW-1:0] alert_class = 'he4,
+ bit [alert_pkg::NAlerts-1:0] alert_en = '1,
+ bit [TL_DW-1:0] alert_class = 'h0,
bit [TL_DW-1:0] classA_ctrl = 'h393d);
// TODO: cfg_interrupts does not disable interrupt, need debug
//cfg_interrupts(.interrupts(interrupts), .enable(1'b1));
@@ -40,11 +41,25 @@
csr_update(.csr(ral.classa_ctrl));
endtask
- virtual task drive_alert(int alert_index);
- alert_sender_seq alert_seq;
- `uvm_create_on(alert_seq, p_sequencer.alert_host_seqr_h[alert_index]);
- `DV_CHECK_RANDOMIZE_FATAL(alert_seq)
- `uvm_send(alert_seq)
+ virtual task drive_alert(bit[alert_pkg::NAlerts-1:0] alert_trigger);
+ fork
+ begin : isolation_fork
+ foreach (alert_trigger[i]) begin
+ if (alert_trigger[i]) begin
+ automatic int index = i;
+ fork
+ begin
+ alert_sender_seq alert_seq;
+ `uvm_create_on(alert_seq, p_sequencer.alert_host_seqr_h[index]);
+ `DV_CHECK_RANDOMIZE_FATAL(alert_seq)
+ `uvm_send(alert_seq)
+ end
+ join_none
+ end
+ end
+ wait fork;
+ end
+ join
endtask
virtual task clear_esc();
diff --git a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sanity_vseq.sv b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sanity_vseq.sv
index c4b1409..d58b122 100644
--- a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sanity_vseq.sv
+++ b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sanity_vseq.sv
@@ -8,12 +8,9 @@
`uvm_object_new
- rand bit[3:0] intr_en;
-
- // temp disable
- constraint only_enable_intr_class_a_c {
- intr_en inside {0, 1};
- }
+ rand bit [NUM_ALERT_HANDLER_CLASSES-1:0] intr_en;
+ rand bit [alert_pkg::NAlerts-1:0] alert_trigger;
+ rand bit [alert_pkg::NAlerts-1:0] alert_en;
task body();
run_esc_rsp_seq_nonblocking();
@@ -26,17 +23,19 @@
map_e2.value inside {[0:NUM_ALERT_HANDLER_CLASSES-1]};
map_e3.value inside {[0:NUM_ALERT_HANDLER_CLASSES-1]};
)
- `uvm_info(`gfn, $sformatf("starting seq %0d/%0d: intr_en=%0b", i, num_trans, intr_en),
- UVM_LOW)
+ `uvm_info(`gfn, $sformatf("starting seq %0d/%0d: intr_en=%0b, alert_trigger=%0b, alert_en=%0b",
+ i, num_trans, intr_en, alert_trigger, alert_en), UVM_LOW)
`uvm_info(`gfn, ral.classa_ctrl.sprint(), UVM_HIGH)
- alert_handler_init(.intr_en(intr_en), .classA_ctrl(ral.classa_ctrl.get()));
- drive_alert(0);
- if (intr_en != 0) begin
- wait(cfg.intr_vif.pins[0] === 1'b1);
- check_interrupts(.interrupts((1)), .check_set(1'b1));
- end else begin
- csr_spinwait(.ptr(ral.intr_state.classa), .exp_data(1'b1));
- csr_wr(.csr(ral.intr_state), .value(1));
+ alert_handler_init(.intr_en(intr_en), .alert_en(alert_en), .classA_ctrl(ral.classa_ctrl.get()));
+ drive_alert(alert_trigger);
+ if (alert_en & alert_trigger) begin
+ if (intr_en[0] != 0) begin
+ wait(cfg.intr_vif.pins[0] === 1'b1);
+ check_interrupts(.interrupts((1)), .check_set(1'b1));
+ end else begin
+ csr_spinwait(.ptr(ral.intr_state.classa), .exp_data(1'b1));
+ csr_wr(.csr(ral.intr_state), .value(1));
+ end
end
// TODO: check escalation phases once the escalation agent is connected
if (ral.classa_ctrl.en_e0.get() | ral.classa_ctrl.en_e1.get() |