[dv/alert_handler] Support esc resp integrity fail
Add support for esc response int fail
Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/dv/sv/alert_esc_agent/alert_esc_agent_pkg.sv b/hw/dv/sv/alert_esc_agent/alert_esc_agent_pkg.sv
index f8cb402..14e7724 100644
--- a/hw/dv/sv/alert_esc_agent/alert_esc_agent_pkg.sv
+++ b/hw/dv/sv/alert_esc_agent/alert_esc_agent_pkg.sv
@@ -42,6 +42,12 @@
HasAlertBeforeAfterIntFail = 'b11
} alert_sig_int_err_e;
+ typedef enum {
+ NoResponse,
+ RandResponse,
+ SigPNIntErr
+ } resp_sig_int_err_e;
+
// macro includes
`include "uvm_macros.svh"
`include "dv_macros.svh"
diff --git a/hw/dv/sv/alert_esc_agent/alert_esc_if.sv b/hw/dv/sv/alert_esc_agent/alert_esc_if.sv
index e9a7b41..2b6cd9d 100644
--- a/hw/dv/sv/alert_esc_agent/alert_esc_if.sv
+++ b/hw/dv/sv/alert_esc_agent/alert_esc_if.sv
@@ -124,11 +124,11 @@
// tasks for escalator sender/receiver pairs
task automatic wait_esc();
- while (esc_tx.esc_p !== 1'b1) @(monitor_cb);
+ while (esc_tx.esc_p === 1'b0 && esc_tx.esc_n === 1'b1) @(monitor_cb);
endtask : wait_esc
task automatic wait_esc_complete();
- while (esc_tx.esc_p !== 1'b0) @(monitor_cb);
+ while (esc_tx.esc_p === 1'b1 && esc_tx.esc_n === 1'b0) @(monitor_cb);
endtask : wait_esc_complete
task automatic reset_esc();
@@ -146,12 +146,15 @@
receiver_cb.esc_rx.resp_n <= 1'b1;
endtask
- function automatic bit get_esc_p();
- return monitor_cb.esc_tx.esc_p;
+ function automatic bit get_esc();
+ return monitor_cb.esc_tx.esc_p && !monitor_cb.esc_tx.esc_n;
endfunction
function automatic bit get_resp_p();
return monitor_cb.esc_rx.resp_p;
endfunction
+ function automatic bit get_resp_n();
+ return monitor_cb.esc_rx.resp_n;
+ endfunction
endinterface: alert_esc_if
diff --git a/hw/dv/sv/alert_esc_agent/alert_esc_seq_item.sv b/hw/dv/sv/alert_esc_agent/alert_esc_seq_item.sv
index 6cfad90..5ac8555 100644
--- a/hw/dv/sv/alert_esc_agent/alert_esc_seq_item.sv
+++ b/hw/dv/sv/alert_esc_agent/alert_esc_seq_item.sv
@@ -16,7 +16,8 @@
rand bit r_esc_rsp;
rand bit int_err;
rand bit timeout;
- rand alert_sig_int_err_e int_err_scenario;
+ rand alert_sig_int_err_e alert_int_err_type;
+ rand resp_sig_int_err_e resp_int_err_type;
// for monitor only
rand alert_esc_trans_type_e alert_esc_type;
@@ -46,8 +47,9 @@
}
// TODO: temp constraint, will support soon
- constraint sig_int_fail_c {
- int_err_scenario == NoAlertBeforeAfterIntFail;
+ constraint sig_int_err_c {
+ alert_int_err_type == NoAlertBeforeAfterIntFail;
+ resp_int_err_type == RandResponse;
}
`uvm_object_utils_begin(alert_esc_seq_item)
@@ -58,6 +60,13 @@
`uvm_field_int (r_esc_rsp, UVM_DEFAULT)
`uvm_field_int (int_err, UVM_DEFAULT)
`uvm_field_int (timeout, UVM_DEFAULT)
+ `uvm_field_int (ping_delay, UVM_DEFAULT)
+ `uvm_field_int (ack_delay, UVM_DEFAULT)
+ `uvm_field_int (ack_stable, UVM_DEFAULT)
+ `uvm_field_int (alert_delay, UVM_DEFAULT)
+ `uvm_field_int (int_err_cyc, UVM_DEFAULT)
+ `uvm_field_enum(alert_sig_int_err_e, alert_int_err_type, UVM_DEFAULT)
+ `uvm_field_enum(resp_sig_int_err_e, resp_int_err_type, UVM_DEFAULT)
`uvm_field_enum(alert_esc_trans_type_e, alert_esc_type, UVM_DEFAULT)
`uvm_field_enum(alert_handshake_e, alert_handshake_sta, UVM_DEFAULT)
`uvm_field_enum(esc_handshake_e, esc_handshake_sta, UVM_DEFAULT)
diff --git a/hw/dv/sv/alert_esc_agent/alert_sender_driver.sv b/hw/dv/sv/alert_esc_agent/alert_sender_driver.sv
index 86eedcb..e20eb63 100644
--- a/hw/dv/sv/alert_esc_agent/alert_sender_driver.sv
+++ b/hw/dv/sv/alert_esc_agent/alert_sender_driver.sv
@@ -79,9 +79,9 @@
reset_alert_pins(ack_delay);
// alert signals integrity fail
end else begin
- if (req.int_err_scenario & HasAlertBeforeIntFailOnly) set_alert_pins(alert_delay);
+ if (req.alert_int_err_type & HasAlertBeforeIntFailOnly) set_alert_pins(alert_delay);
random_drive_int_fail(req.int_err_cyc);
- if (req.int_err_scenario & HasAlertAfterIntFailOnly) begin
+ if (req.alert_int_err_type & HasAlertAfterIntFailOnly) begin
set_alert_pins(alert_delay);
end else begin
cfg.vif.reset_alert();
diff --git a/hw/dv/sv/alert_esc_agent/esc_monitor.sv b/hw/dv/sv/alert_esc_agent/esc_monitor.sv
index 39b11fd..eb87c14 100644
--- a/hw/dv/sv/alert_esc_agent/esc_monitor.sv
+++ b/hw/dv/sv/alert_esc_agent/esc_monitor.sv
@@ -19,6 +19,7 @@
fork
esc_thread(phase);
reset_thread(phase);
+ int_fail_thread(phase);
join_none
endtask : run_phase
@@ -34,7 +35,7 @@
alert_esc_seq_item req;
bit esc_p;
forever @(cfg.vif.monitor_cb) begin
- if (!esc_p && cfg.vif.get_esc_p() === 1'b1) begin
+ if (!esc_p && cfg.vif.get_esc() === 1'b1) begin
phase.raise_objection(this, $sformatf("%s objection raised", `gfn));
req = alert_esc_seq_item::type_id::create("req");
req.alert_esc_type = AlertEscSigTrans;
@@ -52,7 +53,7 @@
begin : wait_esc_handshake
@(cfg.vif.monitor_cb);
check_esc_resp_toggle(req);
- while (cfg.vif.get_esc_p() === 1) check_esc_resp_toggle(req);
+ while (cfg.vif.get_esc() === 1) check_esc_resp_toggle(req);
if (req.esc_handshake_sta != EscIntFail) begin
req.esc_handshake_sta = EscRespComplete;
end
@@ -66,10 +67,24 @@
alert_esc_port.write(req);
phase.drop_objection(this, $sformatf("%s objection dropped", `gfn));
end
- esc_p = cfg.vif.get_esc_p();
+ esc_p = cfg.vif.get_esc();
end
endtask : esc_thread
+ virtual task int_fail_thread(uvm_phase phase);
+ alert_esc_seq_item req;
+ forever @(cfg.vif.monitor_cb) begin
+ while (cfg.vif.get_esc() === 1'b0) begin
+ @(cfg.vif.monitor_cb);
+ if (cfg.vif.get_resp_p() === 1'b1 && cfg.vif.get_resp_n() == 1'b0) begin
+ req = alert_esc_seq_item::type_id::create("req");
+ req.alert_esc_type = AlertEscIntFail;
+ alert_esc_port.write(req);
+ end
+ end
+ end
+ endtask : int_fail_thread
+
virtual task check_esc_resp_toggle(alert_esc_seq_item req);
if (cfg.vif.get_resp_p() != 1) req.esc_handshake_sta = EscIntFail;
@(cfg.vif.monitor_cb);
diff --git a/hw/dv/sv/alert_esc_agent/esc_receiver_driver.sv b/hw/dv/sv/alert_esc_agent/esc_receiver_driver.sv
index 2d7878d..0559534 100644
--- a/hw/dv/sv/alert_esc_agent/esc_receiver_driver.sv
+++ b/hw/dv/sv/alert_esc_agent/esc_receiver_driver.sv
@@ -1,7 +1,6 @@
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
-//
// ---------------------------------------------
// Alert_handler receiver driver
@@ -27,25 +26,48 @@
alert_esc_seq_item req, rsp;
wait(r_esc_rsp_q.size() > 0);
req = r_esc_rsp_q.pop_front();
- $cast(rsp, req.clone());
- rsp.set_id_info(req);
- `uvm_info(`gfn,
- $sformatf("starting to send receiver item, esc_rsp=%0b, int_fail=%0b",
- req.r_esc_rsp, req.int_err), UVM_HIGH)
+ fork
+ begin
+ $cast(rsp, req.clone());
+ rsp.set_id_info(req);
+ `uvm_info(`gfn,
+ $sformatf("starting to send receiver item, esc_rsp=%0b, int_fail=%0b",
+ req.r_esc_rsp, req.int_err), UVM_HIGH)
- cfg.vif.wait_esc();
- @(cfg.vif.receiver_cb);
- while (cfg.vif.receiver_cb.esc_tx.esc_p === 1'b1) begin
- cfg.vif.set_resp();
- @(cfg.vif.receiver_cb);
- cfg.vif.reset_resp();
- @(cfg.vif.receiver_cb);
- end
-
- `uvm_info(`gfn,
- $sformatf("finished sending receiver item, esc_rsp=%0b, int_fail=%0b",
- req.r_esc_rsp, req.int_err), UVM_HIGH)
- seq_item_port.put_response(rsp);
- end
+ // toggle resp signals only when esc signals are not set
+ if (req.int_err && req.resp_int_err_type == RandResponse) begin
+ cfg.vif.wait_esc_complete();
+ repeat (req.int_err_cyc) begin
+ if (cfg.vif.get_esc() === 1'b0) begin
+ randcase
+ 1: cfg.vif.set_resp();
+ 1: cfg.vif.reset_resp();
+ endcase
+ end else begin
+ break;
+ end
+ @(cfg.vif.receiver_cb);
+ end
+ if (cfg.vif.get_esc() === 1'b0) cfg.vif.reset_resp();
+ end else begin
+ cfg.vif.wait_esc();
+ @(cfg.vif.receiver_cb);
+ while (cfg.vif.get_esc() === 1'b1) toggle_resp_signal();
+ end
+ `uvm_info(`gfn,
+ $sformatf("finished sending receiver item, esc_rsp=%0b, int_fail=%0b",
+ req.r_esc_rsp, req.int_err), UVM_HIGH)
+ seq_item_port.put_response(rsp);
+ end
+ join_none
+ end // end forever
endtask : rsp_escalator
+
+ task toggle_resp_signal();
+ cfg.vif.set_resp();
+ @(cfg.vif.receiver_cb);
+ cfg.vif.reset_resp();
+ @(cfg.vif.receiver_cb);
+ endtask : toggle_resp_signal
+
endclass : esc_receiver_driver
diff --git a/hw/dv/sv/alert_esc_agent/seq_lib/esc_receiver_esc_rsp_seq.sv b/hw/dv/sv/alert_esc_agent/seq_lib/esc_receiver_esc_rsp_seq.sv
index 69db9de..de1f8e7 100644
--- a/hw/dv/sv/alert_esc_agent/seq_lib/esc_receiver_esc_rsp_seq.sv
+++ b/hw/dv/sv/alert_esc_agent/seq_lib/esc_receiver_esc_rsp_seq.sv
@@ -12,12 +12,15 @@
`uvm_object_utils(esc_receiver_esc_rsp_seq)
`uvm_object_new
+ rand bit int_err;
+
virtual task body();
`uvm_info(`gfn, $sformatf("starting escalator receiver transfer"), UVM_HIGH)
req = alert_esc_seq_item::type_id::create("req");
start_item(req);
`DV_CHECK_RANDOMIZE_WITH_FATAL(req,
r_esc_rsp == 1;
+ int_err == local::int_err;
)
`uvm_info(`gfn, $sformatf("seq_item: esc_rsp, int_err=%0b", req.int_err), UVM_HIGH)
finish_item(req);
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 594481b..2ad3a43 100644
--- a/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
+++ b/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
@@ -126,6 +126,10 @@
act_item.esc_handshake_sta == EscRespComplete) begin
check_esc_phase(phase_info);
end
+ if (act_item.alert_esc_type == AlertEscIntFail) begin
+ bit [TL_DW-1:0] loc_alert_en = ral.loc_alert_en.get_mirrored_value();
+ if (loc_alert_en[LocalEscIntFail]) process_alert_sig(index, 1, LocalEscIntFail);
+ end
end
join_none
end
@@ -335,12 +339,14 @@
for (int phase_i = 0; phase_i < NUM_ESC_PHASES; phase_i++) begin
int phase_thresh = reg_esc_phase_cycs_per_class_q[class_i][phase_i]
.get_mirrored_value();
- @(cfg.clk_rst_vif.cb);
- intr_timer_per_class[class_i] = 1;
- while (under_esc_classes[class_i] != 0 &&
- intr_timer_per_class[class_i] < phase_thresh) begin
+ if (!under_reset && under_esc_classes[class_i]) begin
@(cfg.clk_rst_vif.cb);
- intr_timer_per_class[class_i] += 1;
+ intr_timer_per_class[class_i] = 1;
+ while (under_esc_classes[class_i] != 0 &&
+ intr_timer_per_class[class_i] < phase_thresh) begin
+ @(cfg.clk_rst_vif.cb);
+ intr_timer_per_class[class_i] += 1;
+ end
end
end
@(cfg.clk_rst_vif.cb);
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 bb04d53..a257f7f 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
@@ -86,6 +86,27 @@
join
endtask
+ virtual task drive_esc_resp(bit[alert_pkg::N_ESC_SEV-1:0] esc_int_err);
+ fork
+ begin : isolation_fork
+ foreach (esc_int_err[i]) begin
+ if (esc_int_err[i]) begin
+ automatic int index = i;
+ fork
+ begin
+ esc_receiver_esc_rsp_seq esc_seq;
+ `uvm_create_on(esc_seq, p_sequencer.esc_device_seqr_h[index]);
+ `DV_CHECK_RANDOMIZE_WITH_FATAL(esc_seq, int_err == 1;)
+ `uvm_send(esc_seq)
+ end
+ join_none
+ end
+ end
+ wait fork;
+ end
+ join
+ endtask
+
virtual task clear_esc();
csr_wr(.csr(ral.classa_clr), .value(1));
csr_wr(.csr(ral.classb_clr), .value(1));
@@ -149,7 +170,7 @@
forever begin
esc_receiver_esc_rsp_seq esc_seq =
esc_receiver_esc_rsp_seq::type_id::create("esc_seq");
- `DV_CHECK_RANDOMIZE_FATAL(esc_seq);
+ `DV_CHECK_RANDOMIZE_WITH_FATAL(esc_seq, int_err == 0;);
esc_seq.start(p_sequencer.esc_device_seqr_h[index]);
end
join_none
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 bce8d80..eba7894 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
@@ -15,6 +15,7 @@
rand bit [alert_pkg::NAlerts*2-1:0] alert_class_map;
rand bit [NUM_LOCAL_ALERT-1:0] local_alert_en;
rand bit [NUM_LOCAL_ALERT*2-1:0] local_alert_class_map;
+ rand bit [alert_pkg::N_ESC_SEV-1:0] esc_int_err;
rand bit do_clr_esc;
rand bit do_wr_phases_cyc;
@@ -49,6 +50,7 @@
constraint sig_int_c {
alert_int_err == 0;
+ esc_int_err == 0;
}
task body();
@@ -75,6 +77,7 @@
if (do_esc_intr_timeout) wr_intr_timeout_cycle(intr_timeout_cyc);
wr_class_accum_threshold(accum_thresh);
+ if (esc_int_err) drive_esc_resp(esc_int_err);
// drive alert
drive_alert(alert_trigger, alert_int_err);
diff --git a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sig_int_fail_vseq.sv b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sig_int_fail_vseq.sv
index f23ae0e..8be3ae7 100644
--- a/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sig_int_fail_vseq.sv
+++ b/hw/ip/alert_handler/dv/env/seq_lib/alert_handler_sig_int_fail_vseq.sv
@@ -14,12 +14,13 @@
}
constraint enable_alert_int_fail_only_c {
- local_alert_en == (1 << LocalAlertIntFail); // TODO: temp constraint, take off once scb support esc int fail
+ local_alert_en inside {1 << LocalAlertIntFail, 1 << LocalEscIntFail};
+ // TODO: temp constraint, take off once scb support ping response fail
}
function void pre_randomize();
this.enable_one_alert_c.constraint_mode(0);
- this.enable_classa_only_c.constraint_mode(0);
+ // TODO: add support this.enable_classa_only_c.constraint_mode(0);
endfunction
endclass : alert_handler_sig_int_fail_vseq