[dv/alert_handler] support escalator
Add support for the escalator pairs in alert_agent
Add a driver and monitor for escalator pairs
Add escalator signals into alert_if
Signed-off-by: Cindy Chen <chencindy@google.com>
diff --git a/hw/dv/sv/alert_agent/alert_agent.core b/hw/dv/sv/alert_agent/alert_agent.core
index 80db449..23af6fe 100644
--- a/hw/dv/sv/alert_agent/alert_agent.core
+++ b/hw/dv/sv/alert_agent/alert_agent.core
@@ -16,15 +16,21 @@
- alert_agent_cfg.sv: {is_include_file: true}
- alert_agent.sv: {is_include_file: true}
- alert_agent_cov.sv: {is_include_file: true}
+ - alert_esc_base_driver.sv: {is_include_file: true}
- alert_sender_driver.sv: {is_include_file: true}
- alert_receiver_driver.sv: {is_include_file: true}
+ - alert_sender_driver.sv: {is_include_file: true}
+ - esc_receiver_driver.sv: {is_include_file: true}
+ - alert_esc_base_monitor.sv: {is_include_file: true}
- alert_monitor.sv: {is_include_file: true}
+ - esc_monitor.sv: {is_include_file: true}
- alert_seq_item.sv: {is_include_file: true}
- alert_sequencer.sv: {is_include_file: true}
- seq_lib/alert_receiver_alert_rsp_seq.sv: {is_include_file: true}
- seq_lib/alert_receiver_seq.sv: {is_include_file: true}
- seq_lib/alert_sender_ping_rsp_seq.sv: {is_include_file: true}
- seq_lib/alert_sender_seq.sv: {is_include_file: true}
+ - seq_lib/esc_receiver_esc_rsp_seq.sv: {is_include_file: true}
file_type: systemVerilogSource
targets:
diff --git a/hw/dv/sv/alert_agent/alert_agent.sv b/hw/dv/sv/alert_agent/alert_agent.sv
index e65db00..77989c2 100644
--- a/hw/dv/sv/alert_agent/alert_agent.sv
+++ b/hw/dv/sv/alert_agent/alert_agent.sv
@@ -7,11 +7,9 @@
// ---------------------------------------------
class alert_agent extends dv_base_agent#(
.CFG_T (alert_agent_cfg),
- .DRIVER_T (alert_base_driver),
- .HOST_DRIVER_T (alert_sender_driver),
- .DEVICE_DRIVER_T (alert_receiver_driver),
+ .DRIVER_T (alert_esc_base_driver),
.SEQUENCER_T (alert_sequencer),
- .MONITOR_T (alert_monitor),
+ .MONITOR_T (alert_esc_base_monitor),
.COV_T (alert_agent_cov)
);
@@ -20,6 +18,34 @@
`uvm_component_new
function void build_phase(uvm_phase phase);
+ alert_agent_cfg cfg;
+ if (!uvm_config_db#(CFG_T)::get(this, "", "cfg", cfg)) begin
+ `uvm_fatal(`gfn, $sformatf("failed to get %s from uvm_config_db", cfg.get_type_name()))
+ end
+ // override monitor
+ if (cfg.is_alert) begin
+ alert_esc_base_monitor::type_id::set_type_override(alert_monitor::get_type());
+ end else begin
+ alert_esc_base_monitor::type_id::set_type_override(esc_monitor::get_type());
+ end
+
+ // override driver
+ if (cfg.is_active) begin
+ if (cfg.is_alert) begin
+ if (cfg.if_mode == Host) begin
+ alert_esc_base_driver::type_id::set_type_override(alert_sender_driver::get_type());
+ end else begin
+ alert_esc_base_driver::type_id::set_type_override(alert_receiver_driver::get_type());
+ end
+ end else begin
+ if (cfg.if_mode == Host) begin
+ alert_esc_base_driver::type_id::set_type_override(esc_sender_driver::get_type());
+ end else begin
+ alert_esc_base_driver::type_id::set_type_override(esc_receiver_driver::get_type());
+ end
+ end
+ end
+
super.build_phase(phase);
// get alert_if handle
if (!uvm_config_db#(virtual alert_if)::get(this, "", "vif", cfg.vif)) begin
diff --git a/hw/dv/sv/alert_agent/alert_agent_cfg.sv b/hw/dv/sv/alert_agent/alert_agent_cfg.sv
index 017067f..2bab10d 100644
--- a/hw/dv/sv/alert_agent/alert_agent_cfg.sv
+++ b/hw/dv/sv/alert_agent/alert_agent_cfg.sv
@@ -8,6 +8,8 @@
// ---------------------------------------------
class alert_agent_cfg extends dv_base_agent_cfg;
virtual alert_if vif;
+
+ bit is_alert = 1;
// sender mode
bit use_seq_item_alert_delay;
int unsigned alert_delay_min = 0;
@@ -30,13 +32,13 @@
`uvm_object_utils_begin(alert_agent_cfg)
`uvm_field_int(alert_delay_min, UVM_DEFAULT)
- `uvm_field_int(alert_delay_min, UVM_DEFAULT)
+ `uvm_field_int(alert_delay_max, UVM_DEFAULT)
`uvm_field_int(ack_delay_min, UVM_DEFAULT)
- `uvm_field_int(ack_delay_min, UVM_DEFAULT)
+ `uvm_field_int(ack_delay_max, UVM_DEFAULT)
`uvm_field_int(ack_stable_min, UVM_DEFAULT)
- `uvm_field_int(ack_stable_min, UVM_DEFAULT)
+ `uvm_field_int(ack_stable_max, UVM_DEFAULT)
`uvm_field_int(ping_delay_min, UVM_DEFAULT)
- `uvm_field_int(ping_delay_min, UVM_DEFAULT)
+ `uvm_field_int(ping_delay_max, UVM_DEFAULT)
`uvm_object_utils_end
`uvm_object_new
diff --git a/hw/dv/sv/alert_agent/alert_agent_pkg.sv b/hw/dv/sv/alert_agent/alert_agent_pkg.sv
index 40768d6..6854799 100644
--- a/hw/dv/sv/alert_agent/alert_agent_pkg.sv
+++ b/hw/dv/sv/alert_agent/alert_agent_pkg.sv
@@ -11,22 +11,29 @@
typedef class alert_seq_item;
typedef class alert_agent_cfg;
- // reuse dv_base_driver as is with the right parameter set
- typedef dv_base_driver #(alert_seq_item, alert_agent_cfg) alert_base_driver;
typedef enum {
- PingTrans,
- AlertTrans,
- IntFail
- } alert_type_e;
+ AlertEscPingTrans,
+ AlertEscSigTrans,
+ AlertEscIntFail
+ } alert_esc_trans_type_e;
typedef enum {
AlertReceived,
- AckReceived,
+ AlertAckReceived,
AlertComplete,
- AckComplete
+ AlertAckComplete
} alert_handshake_e;
+ typedef enum {
+ EscPingReceived,
+ EscReceived,
+ EscRespReceived,
+ EscComplete,
+ EscRespComplete,
+ EscIntFail
+ } esc_handshake_e;
+
// macro includes
`include "uvm_macros.svh"
`include "dv_macros.svh"
@@ -35,13 +42,19 @@
`include "alert_seq_item.sv"
`include "alert_agent_cfg.sv"
`include "alert_agent_cov.sv"
+ `include "alert_esc_base_driver.sv"
`include "alert_sender_driver.sv"
`include "alert_receiver_driver.sv"
+ `include "esc_sender_driver.sv"
+ `include "esc_receiver_driver.sv"
`include "alert_sequencer.sv"
+ `include "alert_esc_base_monitor.sv"
`include "alert_monitor.sv"
+ `include "esc_monitor.sv"
`include "alert_agent.sv"
`include "seq_lib/alert_receiver_alert_rsp_seq.sv"
`include "seq_lib/alert_receiver_seq.sv"
`include "seq_lib/alert_sender_ping_rsp_seq.sv"
`include "seq_lib/alert_sender_seq.sv"
+ `include "seq_lib/esc_receiver_esc_rsp_seq.sv"
endpackage
diff --git a/hw/dv/sv/alert_agent/alert_esc_base_driver.sv b/hw/dv/sv/alert_agent/alert_esc_base_driver.sv
new file mode 100644
index 0000000..a566234
--- /dev/null
+++ b/hw/dv/sv/alert_agent/alert_esc_base_driver.sv
@@ -0,0 +1,45 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+
+// ---------------------------------------------
+// Alert_esc_base driver
+// ---------------------------------------------
+class alert_esc_base_driver extends dv_base_driver#(alert_seq_item, alert_agent_cfg);
+ alert_seq_item r_alert_ping_send_q[$], r_alert_rsp_q[$], r_esc_rsp_q[$],
+ s_alert_send_q[$], s_alert_ping_rsp_q[$];
+
+ `uvm_component_utils(alert_esc_base_driver)
+
+ `uvm_component_new
+
+ // drive trans received from sequencer
+ virtual task get_and_drive();
+ fork
+ get_req();
+ drive_req();
+ join_none
+ endtask
+
+ virtual task drive_req();
+ `uvm_fatal(`gfn, "this is implemented as pure virtual task - please extend")
+ endtask
+
+ virtual task get_req();
+ forever begin
+ alert_seq_item req_clone;
+ seq_item_port.get(req);
+ $cast(req_clone, req.clone());
+ req_clone.set_id_info(req);
+ // TODO: if any of the queue size is larger than 2, need additional support
+ if (req.r_alert_ping_send) r_alert_ping_send_q.push_back(req_clone);
+ if (req.r_alert_rsp) r_alert_rsp_q.push_back(req_clone);
+ if (req.r_esc_rsp) r_esc_rsp_q.push_back(req_clone);
+ // sender mode
+ if (req.s_alert_send) s_alert_send_q.push_back(req_clone);
+ if (req.s_alert_ping_rsp) s_alert_ping_rsp_q.push_back(req_clone);
+ end
+ endtask : get_req
+
+endclass
diff --git a/hw/dv/sv/alert_agent/alert_esc_base_monitor.sv b/hw/dv/sv/alert_agent/alert_esc_base_monitor.sv
new file mode 100644
index 0000000..966cc58
--- /dev/null
+++ b/hw/dv/sv/alert_agent/alert_esc_base_monitor.sv
@@ -0,0 +1,29 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+
+// ---------------------------------------------
+// Alert sender receiver interface base monitor
+// ---------------------------------------------
+
+class alert_esc_base_monitor extends dv_base_monitor#(
+ .ITEM_T (alert_seq_item),
+ .CFG_T (alert_agent_cfg),
+ .COV_T (alert_agent_cov)
+ );
+
+ `uvm_component_utils(alert_esc_base_monitor)
+ uvm_analysis_port #(alert_seq_item) alert_port;
+ `uvm_component_new
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+ alert_port = new("alert_port", this);
+ endfunction : build_phase
+
+ virtual task run_phase(uvm_phase phase);
+ // TODO: implement the run phase
+ endtask : run_phase
+
+endclass
diff --git a/hw/dv/sv/alert_agent/alert_if.sv b/hw/dv/sv/alert_agent/alert_if.sv
index d1fb357..265eaed 100644
--- a/hw/dv/sv/alert_agent/alert_if.sv
+++ b/hw/dv/sv/alert_agent/alert_if.sv
@@ -8,25 +8,35 @@
interface alert_if(input clk, input rst_n);
wire prim_pkg::alert_tx_t alert_tx;
wire prim_pkg::alert_rx_t alert_rx;
+ wire prim_pkg::esc_tx_t esc_tx;
+ wire prim_pkg::esc_rx_t esc_rx;
clocking sender_cb @(posedge clk);
input rst_n;
output alert_tx;
input alert_rx;
+ output esc_tx;
+ input esc_rx;
endclocking
clocking receiver_cb @(posedge clk);
input rst_n;
input alert_tx;
output alert_rx;
+ input esc_tx;
+ output esc_rx;
endclocking
clocking monitor_cb @(posedge clk);
- input rst_n;
- input alert_tx;
- input alert_rx;
+ input rst_n;
+ input alert_tx;
+ input alert_rx;
+ input esc_tx;
+ input esc_rx;
endclocking
+ // tasks for alert sender/receiver pairs
+
task automatic wait_alert();
while (alert_tx.alert_p !== 1'b1) @(monitor_cb);
endtask : wait_alert
@@ -81,4 +91,45 @@
receiver_cb.alert_rx.ping_n <= 1'b1;
endtask
+ function automatic bit get_ack_p();
+ return monitor_cb.alert_rx.ack_p;
+ endfunction
+
+ function automatic bit get_alert_p();
+ return monitor_cb.alert_tx.alert_p;
+ endfunction
+
+ function automatic bit get_ping_p();
+ return monitor_cb.alert_rx.ping_p;
+ endfunction
+
+ // tasks for escalator sender/receiver pairs
+
+ task automatic wait_esc();
+ while (esc_tx.esc_p !== 1'b1) @(monitor_cb);
+ endtask : wait_esc
+
+ task automatic reset_esc();
+ sender_cb.esc_tx.esc_p <= 1'b0;
+ sender_cb.esc_tx.esc_n <= 1'b1;
+ endtask
+
+ task automatic set_resp();
+ receiver_cb.esc_rx.resp_p <= 1'b1;
+ receiver_cb.esc_rx.resp_n <= 1'b0;
+ endtask
+
+ task automatic reset_resp();
+ receiver_cb.esc_rx.resp_p <= 1'b0;
+ receiver_cb.esc_rx.resp_n <= 1'b1;
+ endtask
+
+ function automatic bit get_esc_p();
+ return monitor_cb.esc_tx.esc_p;
+ endfunction
+
+ function automatic bit get_resp_p();
+ return monitor_cb.esc_rx.resp_p;
+ endfunction
+
endinterface: alert_if
diff --git a/hw/dv/sv/alert_agent/alert_monitor.sv b/hw/dv/sv/alert_agent/alert_monitor.sv
index e73b321..210c875 100644
--- a/hw/dv/sv/alert_agent/alert_monitor.sv
+++ b/hw/dv/sv/alert_agent/alert_monitor.sv
@@ -7,25 +7,14 @@
// Alert sender receiver interface monitor
// ---------------------------------------------
-class alert_monitor extends dv_base_monitor#(
- .ITEM_T (alert_seq_item),
- .CFG_T (alert_agent_cfg),
- .COV_T (alert_agent_cov)
- );
+class alert_monitor extends alert_esc_base_monitor;
`uvm_component_utils(alert_monitor)
bit under_ping_rsp;
- uvm_analysis_port #(alert_seq_item) alert_port;
-
`uvm_component_new
- function void build_phase(uvm_phase phase);
- super.build_phase(phase);
- alert_port = new("alert_port", this);
- endfunction : build_phase
-
//TODO: currently only support sync mode
//TODO: add support for signal int err and reset
virtual task run_phase(uvm_phase phase);
@@ -48,11 +37,11 @@
alert_seq_item req;
bit ping_p;
forever @(cfg.vif.monitor_cb) begin
- if (ping_p != cfg.vif.monitor_cb.alert_rx.ping_p) begin
+ if (ping_p != cfg.vif.get_ping_p()) begin
phase.raise_objection(this);
under_ping_rsp = 1;
req = alert_seq_item::type_id::create("req");
- req.alert_type = PingTrans;
+ req.alert_esc_type = AlertEscPingTrans;
fork
begin : isolation_fork
fork
@@ -64,25 +53,25 @@
cfg.vif.wait_alert();
req.alert_handshake_sta = AlertReceived;
cfg.vif.wait_ack();
- req.alert_handshake_sta = AckReceived;
+ req.alert_handshake_sta = AlertAckReceived;
cfg.vif.wait_alert_complete();
req.alert_handshake_sta = AlertComplete;
under_ping_rsp = 0;
// TODO: if now another alert triggered, will both sample the ack signal?
cfg.vif.wait_ack_complete();
- req.alert_handshake_sta = AckComplete;
+ req.alert_handshake_sta = AlertAckComplete;
end
join_any
disable fork;
end : isolation_fork
join
`uvm_info("alert_monitor", $sformatf("[%s]: handshake status is %s",
- req.alert_type.name(), req.alert_handshake_sta.name()), UVM_HIGH)
+ req.alert_esc_type.name(), req.alert_handshake_sta.name()), UVM_HIGH)
alert_port.write(req);
phase.drop_objection(this);
under_ping_rsp = 0;
end
- ping_p = cfg.vif.monitor_cb.alert_rx.ping_p;
+ ping_p = cfg.vif.get_ping_p();
end
endtask : ping_thread
@@ -90,10 +79,10 @@
alert_seq_item req;
bit alert_p;
forever @(cfg.vif.monitor_cb) begin
- if (!alert_p && cfg.vif.monitor_cb.alert_tx.alert_p === 1'b1 && !under_ping_rsp) begin
+ if (!alert_p && cfg.vif.get_alert_p() === 1'b1 && !under_ping_rsp) begin
phase.raise_objection(this);
req = alert_seq_item::type_id::create("req");
- req.alert_type = AlertTrans;
+ req.alert_esc_type = AlertEscSigTrans;
req.alert_handshake_sta = AlertReceived;
// Write alert packet to scb when receiving alert signal
alert_port.write(req);
@@ -108,22 +97,22 @@
end
begin : wait_alert_handshake
cfg.vif.wait_ack();
- req.alert_handshake_sta = AckReceived;
+ req.alert_handshake_sta = AlertAckReceived;
cfg.vif.wait_alert_complete();
req.alert_handshake_sta = AlertComplete;
cfg.vif.wait_ack_complete();
- req.alert_handshake_sta = AckComplete;
+ req.alert_handshake_sta = AlertAckComplete;
end
join_any
disable fork;
end : isolation_fork
join
`uvm_info("alert_monitor", $sformatf("[%s]: handshake status is %s",
- req.alert_type.name(), req.alert_handshake_sta.name()), UVM_HIGH)
+ req.alert_esc_type.name(), req.alert_handshake_sta.name()), UVM_HIGH)
alert_port.write(req);
phase.drop_objection(this);
end
- alert_p = cfg.vif.monitor_cb.alert_tx.alert_p;
+ alert_p = cfg.vif.get_alert_p();
end
endtask : alert_thread
diff --git a/hw/dv/sv/alert_agent/alert_receiver_driver.sv b/hw/dv/sv/alert_agent/alert_receiver_driver.sv
index 48bd7fc..8468cbe 100644
--- a/hw/dv/sv/alert_agent/alert_receiver_driver.sv
+++ b/hw/dv/sv/alert_agent/alert_receiver_driver.sv
@@ -6,39 +6,23 @@
// ---------------------------------------------
// Alert_handler receiver driver
// ---------------------------------------------
-class alert_receiver_driver extends alert_base_driver;
-
- alert_seq_item ping_q[$];
- alert_seq_item alert_q[$];
+class alert_receiver_driver extends alert_esc_base_driver;
`uvm_component_utils(alert_receiver_driver)
`uvm_component_new
- virtual task reset_signals();
- cfg.vif.reset_ping();
- cfg.vif.reset_ack();
- endtask
-
- virtual task get_and_drive();
+ virtual task drive_req();
fork
- get_req();
send_ping();
rsp_alert();
join_none
- endtask : get_and_drive
+ endtask : drive_req
- virtual task get_req();
- forever begin
- alert_seq_item req_clone;
- seq_item_port.get(req);
- $cast(req_clone, req.clone());
- req_clone.set_id_info(req);
- // TODO: if ping or alert queue size is larger than 2, need additional support
- if (req.ping_send) ping_q.push_back(req_clone);
- if (req.alert_rsp) alert_q.push_back(req_clone);
- end
- endtask : get_req
+ virtual task reset_signals();
+ cfg.vif.reset_ack();
+ cfg.vif.reset_ping();
+ endtask
virtual task send_ping();
forever begin
@@ -46,15 +30,15 @@
alert_seq_item req, rsp;
ping_delay = (cfg.use_seq_item_ping_delay) ? req.ping_delay :
$urandom_range(cfg.ping_delay_max, cfg.ping_delay_min);
- wait(ping_q.size() > 0);
- req = ping_q.pop_front();
+ wait(r_alert_ping_send_q.size() > 0);
+ req = r_alert_ping_send_q.pop_front();
$cast(rsp, req.clone());
rsp.set_id_info(req);
`uvm_info(`gfn,
$sformatf("starting to send receiver item, ping_send=%0b, alert_rsp=%0b, int_fail=%0b",
- req.ping_send, req.alert_rsp, req.ping_int_err), UVM_HIGH)
+ req.r_alert_ping_send, req.r_alert_rsp, req.int_err), UVM_HIGH)
- if (!req.ping_int_err) begin
+ if (!req.int_err) begin
@(cfg.vif.receiver_cb);
repeat (ping_delay) @(cfg.vif.receiver_cb);
cfg.vif.set_ping();
@@ -75,7 +59,7 @@
`uvm_info(`gfn,
$sformatf("finished sending receiver item, ping_send=%0b, alert_rsp=%0b, int_fail=%0b",
- req.ping_send, req.alert_rsp, req.ping_int_err), UVM_HIGH)
+ req.r_alert_ping_send, req.r_alert_rsp, req.int_err), UVM_HIGH)
seq_item_port.put_response(rsp);
end // end forever
endtask : send_ping
@@ -83,20 +67,20 @@
virtual task rsp_alert();
forever begin
alert_seq_item req, rsp;
- wait(alert_q.size() > 0);
- req = alert_q.pop_front();
+ wait(r_alert_rsp_q.size() > 0);
+ req = r_alert_rsp_q.pop_front();
$cast(rsp, req.clone());
rsp.set_id_info(req);
`uvm_info(`gfn,
$sformatf("starting to send receiver item, ping_send=%0b, alert_rsp=%0b, int_fail=%0b",
- req.ping_send, req.alert_rsp, req.ping_int_err), UVM_HIGH)
+ req.r_alert_ping_send, req.r_alert_rsp, req.int_err), UVM_HIGH)
cfg.vif.wait_alert();
set_ack_pins(req);
`uvm_info(`gfn,
$sformatf("finished sending receiver item, ping_send=%0b, alert_rsp=%0b, int_fail=%0b",
- req.ping_send, req.alert_rsp, req.ping_int_err), UVM_HIGH)
+ req.r_alert_ping_send, req.r_alert_rsp, req.int_err), UVM_HIGH)
seq_item_port.put_response(rsp);
end // end forever
endtask : rsp_alert
@@ -107,7 +91,7 @@
$urandom_range(cfg.ack_delay_max, cfg.ack_delay_min);
ack_stable = (cfg.use_seq_item_ack_stable) ? req.ack_stable :
$urandom_range(cfg.ack_stable_max, cfg.ack_stable_min);
- if (!req.ack_int_err) begin
+ if (!req.int_err) begin
@(cfg.vif.receiver_cb);
repeat (ack_delay) @(cfg.vif.receiver_cb);
cfg.vif.set_ack();
diff --git a/hw/dv/sv/alert_agent/alert_sender_driver.sv b/hw/dv/sv/alert_agent/alert_sender_driver.sv
index 4000a78..4211aa8 100644
--- a/hw/dv/sv/alert_agent/alert_sender_driver.sv
+++ b/hw/dv/sv/alert_agent/alert_sender_driver.sv
@@ -6,9 +6,7 @@
// ---------------------------------------------
// Alert_handler sender driver
// ---------------------------------------------
-class alert_sender_driver extends alert_base_driver;
- alert_seq_item alert_q[$];
- alert_seq_item ping_q[$];
+class alert_sender_driver extends alert_esc_base_driver;
`uvm_component_utils(alert_sender_driver)
@@ -21,41 +19,29 @@
// alert_sender drive responses by sending the alert_p and alert_n
// one alert sent by sequence driving the alert_send signal
// another alert sent by responding to the ping signal
- virtual task get_and_drive();
+ virtual task drive_req();
fork
- get_req();
send_alert();
rsp_ping();
join_none
- endtask : get_and_drive
-
- virtual task get_req();
- forever begin
- alert_seq_item req_clone;
- seq_item_port.get(req);
- $cast(req_clone, req.clone());
- req_clone.set_id_info(req);
- if (req.alert_send) alert_q.push_back(req_clone);
- if (req.ping_rsp) ping_q.push_back(req_clone);
- end
- endtask : get_req
+ endtask : drive_req
virtual task send_alert();
forever begin
alert_seq_item req, rsp;
- wait(alert_q.size() > 0);
- req = alert_q.pop_front();
+ wait(s_alert_send_q.size() > 0);
+ req = s_alert_send_q.pop_front();
$cast(rsp, req.clone());
rsp.set_id_info(req);
`uvm_info(`gfn,
$sformatf("starting to send sender item, alert_send=%0b, ping_rsp=%0b, int_err=%0b",
- req.alert_send, req.ping_rsp, req.alert_int_err), UVM_HIGH)
+ req.s_alert_send, req.s_alert_ping_rsp, req.int_err), UVM_HIGH)
set_alert_pins(req);
`uvm_info(`gfn,
$sformatf("finished sending sender item, alert_send=%0b, ping_rsp=%0b, int_err=%0b",
- req.alert_send, req.ping_rsp, req.alert_int_err), UVM_HIGH)
+ req.s_alert_send, req.s_alert_ping_rsp, req.int_err), UVM_HIGH)
seq_item_port.put_response(rsp);
end // end forever
endtask : send_alert
@@ -63,20 +49,20 @@
virtual task rsp_ping();
forever begin
alert_seq_item req, rsp;
- wait(ping_q.size() > 0);
- req = ping_q.pop_front();
+ wait(s_alert_ping_rsp_q.size() > 0);
+ req = s_alert_ping_rsp_q.pop_front();
$cast(rsp, req.clone());
rsp.set_id_info(req);
`uvm_info(`gfn,
$sformatf("starting to send sender item, alert_send=%0b, ping_rsp=%0b, int_err=%0b",
- req.alert_send, req.ping_rsp, req.alert_int_err), UVM_HIGH)
+ req.s_alert_send, req.s_alert_ping_rsp, req.int_err), UVM_HIGH)
cfg.vif.wait_ping();
set_alert_pins(req);
`uvm_info(`gfn,
$sformatf("finished sending sender item, alert_send=%0b, ping_rsp=%0b, int_err=%0b",
- req.alert_send, req.ping_rsp, req.alert_int_err), UVM_HIGH)
+ req.s_alert_send, req.s_alert_ping_rsp, req.int_err), UVM_HIGH)
seq_item_port.put_response(rsp);
end
endtask : rsp_ping
@@ -88,7 +74,7 @@
ack_delay = (cfg.use_seq_item_ack_delay) ? req.ack_delay :
$urandom_range(cfg.ack_delay_max, cfg.ack_delay_min);
repeat (alert_delay) @(cfg.vif.sender_cb);
- if (!req.alert_int_err) begin
+ if (!req.int_err) begin
@(cfg.vif.sender_cb);
repeat (alert_delay) @(cfg.vif.sender_cb);
cfg.vif.set_alert();
diff --git a/hw/dv/sv/alert_agent/alert_seq_item.sv b/hw/dv/sv/alert_agent/alert_seq_item.sv
index 5eae64f..c6948f6 100644
--- a/hw/dv/sv/alert_agent/alert_seq_item.sv
+++ b/hw/dv/sv/alert_agent/alert_seq_item.sv
@@ -8,18 +8,19 @@
class alert_seq_item extends uvm_sequence_item;
- rand bit alert_send;
- rand bit alert_rsp; // receiver response to alert using ack
- rand bit alert_int_err;
- rand bit ping_rsp; // sender response to ping using alert
- rand bit ack_int_err;
- rand bit ping_send;
- rand bit ping_int_err;
+ // prefix 's' for sender, 'r' for receiver
+ rand bit s_alert_send;
+ rand bit s_alert_ping_rsp; // sender response to ping using alert
+ rand bit r_alert_rsp; // receiver response to alert using ack
+ rand bit r_alert_ping_send;
+ rand bit r_esc_rsp;
+ rand bit int_err;
rand bit timeout;
- // for alert_monitor
- rand alert_type_e alert_type;
- rand alert_handshake_e alert_handshake_sta;
+ // for monitor only
+ rand alert_esc_trans_type_e alert_esc_type;
+ rand alert_handshake_e alert_handshake_sta;
+ rand esc_handshake_e esc_handshake_sta;
// delays
rand int unsigned ping_delay;
@@ -34,17 +35,29 @@
soft ack_stable dist {1 :/ 5, [2:10] :/ 5};
}
+ // if agent is alert mode, cannot send any esc_rsp signal
+ // if agent is esc mode, cannot send any alert related signals
+ constraint alert_esc_mode_c {
+ r_esc_rsp == 1 -> (!s_alert_send && !r_alert_rsp && !r_alert_ping_send && !s_alert_ping_rsp);
+ (s_alert_send || r_alert_rsp || r_alert_ping_send || s_alert_ping_rsp) -> !r_esc_rsp;
+ }
+
+ // temp constraint
+ constraint disable_int_err_c {
+ int_err == 0;
+ }
+
`uvm_object_utils_begin(alert_seq_item)
- `uvm_field_int (alert_send, UVM_DEFAULT)
- `uvm_field_int (alert_int_err, UVM_DEFAULT)
- `uvm_field_int (alert_rsp, UVM_DEFAULT)
- `uvm_field_int (ping_rsp, UVM_DEFAULT)
- `uvm_field_int (ack_int_err, UVM_DEFAULT)
- `uvm_field_int (ping_send, UVM_DEFAULT)
- `uvm_field_int (ping_int_err, UVM_DEFAULT)
- `uvm_field_int (timeout, UVM_DEFAULT)
- `uvm_field_enum(alert_type_e, alert_type, UVM_DEFAULT)
- `uvm_field_enum(alert_handshake_e, alert_handshake_sta, UVM_DEFAULT)
+ `uvm_field_int (s_alert_send, UVM_DEFAULT)
+ `uvm_field_int (s_alert_ping_rsp, UVM_DEFAULT)
+ `uvm_field_int (r_alert_rsp, UVM_DEFAULT)
+ `uvm_field_int (r_alert_ping_send, UVM_DEFAULT)
+ `uvm_field_int (r_esc_rsp, UVM_DEFAULT)
+ `uvm_field_int (int_err, UVM_DEFAULT)
+ `uvm_field_int (timeout, 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)
`uvm_object_utils_end
function new (string name = "");
diff --git a/hw/dv/sv/alert_agent/esc_monitor.sv b/hw/dv/sv/alert_agent/esc_monitor.sv
new file mode 100644
index 0000000..582ee26
--- /dev/null
+++ b/hw/dv/sv/alert_agent/esc_monitor.sv
@@ -0,0 +1,78 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+
+// ---------------------------------------------
+// Escalator sender receiver interface monitor
+// ---------------------------------------------
+
+class esc_monitor extends alert_esc_base_monitor;
+
+ `uvm_component_utils(esc_monitor)
+
+ `uvm_component_new
+
+ //TODO: currently only support sync mode
+ //TODO: add support for signal int err and reset
+ virtual task run_phase(uvm_phase phase);
+ fork
+ esc_thread(phase);
+ reset_thread(phase);
+ join_none
+ endtask : run_phase
+
+ // TODO: placeholder to support reset
+ virtual task reset_thread(uvm_phase phase);
+ forever begin
+ @(negedge cfg.vif.rst_n);
+ @(posedge cfg.vif.rst_n);
+ end
+ endtask : reset_thread
+
+ virtual task esc_thread(uvm_phase phase);
+ alert_seq_item req;
+ bit esc_p;
+ forever @(cfg.vif.monitor_cb) begin
+ if (!esc_p && cfg.vif.get_esc_p() === 1'b1) begin
+ phase.raise_objection(this);
+ req = alert_seq_item::type_id::create("req");
+ req.alert_esc_type = AlertEscSigTrans;
+
+ fork
+ begin : isolation_fork
+ fork
+ begin : esc_timeout
+ repeat (cfg.ping_timeout_cycle) @(cfg.vif.monitor_cb);
+ end
+ begin : wait_esc_handshake
+ @(cfg.vif.monitor_cb);
+ check_esc_resp_toggle(req);
+ while (cfg.vif.get_esc_p() === 1) begin
+ check_esc_resp_toggle(req);
+ end
+ if (req.esc_handshake_sta != EscIntFail) begin
+ req.esc_handshake_sta = EscRespComplete;
+ end
+ end
+ join_any
+ disable fork;
+ end : isolation_fork
+ join
+ `uvm_info("esc_monitor", $sformatf("[%s]: handshake status is %s",
+ req.alert_esc_type.name(), req.esc_handshake_sta.name()), UVM_HIGH)
+ alert_port.write(req);
+ phase.drop_objection(this);
+ end
+ esc_p = cfg.vif.get_esc_p();
+ end
+ endtask : esc_thread
+
+ virtual task check_esc_resp_toggle(alert_seq_item req);
+ if (cfg.vif.get_resp_p() != 1) req.esc_handshake_sta = EscIntFail;
+ @(cfg.vif.monitor_cb);
+ if (cfg.vif.get_resp_p() != 0) req.esc_handshake_sta = EscIntFail;
+ @(cfg.vif.monitor_cb);
+ endtask : check_esc_resp_toggle
+
+endclass : esc_monitor
diff --git a/hw/dv/sv/alert_agent/esc_receiver_driver.sv b/hw/dv/sv/alert_agent/esc_receiver_driver.sv
new file mode 100644
index 0000000..cc763d5
--- /dev/null
+++ b/hw/dv/sv/alert_agent/esc_receiver_driver.sv
@@ -0,0 +1,51 @@
+// 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
+// ---------------------------------------------
+class esc_receiver_driver extends alert_esc_base_driver;
+
+ `uvm_component_utils(esc_receiver_driver)
+
+ `uvm_component_new
+
+ virtual task reset_signals();
+ cfg.vif.reset_resp();
+ endtask
+
+ virtual task drive_req();
+ fork
+ rsp_escalator();
+ join_none
+ endtask : drive_req
+
+ virtual task rsp_escalator();
+ forever begin
+ alert_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)
+
+ 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
+ endtask : rsp_escalator
+endclass : esc_receiver_driver
diff --git a/hw/dv/sv/alert_agent/esc_sender_driver.sv b/hw/dv/sv/alert_agent/esc_sender_driver.sv
new file mode 100644
index 0000000..273b6b7
--- /dev/null
+++ b/hw/dv/sv/alert_agent/esc_sender_driver.sv
@@ -0,0 +1,20 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+
+// ---------------------------------------------
+// Esc sender driver
+// ---------------------------------------------
+class esc_sender_driver extends alert_esc_base_driver;
+
+ `uvm_component_utils(esc_sender_driver)
+
+ `uvm_component_new
+
+ virtual task get_and_drive();
+ // TODO
+ endtask : get_and_drive
+
+endclass : esc_sender_driver
+
diff --git a/hw/dv/sv/alert_agent/seq_lib/alert_receiver_alert_rsp_seq.sv b/hw/dv/sv/alert_agent/seq_lib/alert_receiver_alert_rsp_seq.sv
index b5180dc..d977dc0 100644
--- a/hw/dv/sv/alert_agent/seq_lib/alert_receiver_alert_rsp_seq.sv
+++ b/hw/dv/sv/alert_agent/seq_lib/alert_receiver_alert_rsp_seq.sv
@@ -12,22 +12,15 @@
`uvm_object_utils(alert_receiver_alert_rsp_seq)
`uvm_object_new
- rand bit ack_int_err;
-
- constraint no_int_err_c {
- ack_int_err == 0;
- }
-
virtual task body();
`uvm_info(`gfn, $sformatf("starting alert receiver transfer"), UVM_HIGH)
req = REQ::type_id::create("req");
start_item(req);
`DV_CHECK_RANDOMIZE_WITH_FATAL(req,
- ping_send == 0;
- ping_int_err == 0;
- alert_rsp == 1;
- ack_int_err == local::ack_int_err;
+ r_alert_ping_send == 0;
+ r_alert_rsp == 1;
)
+ `uvm_info(`gfn, $sformatf("seq_item: alert_rsp, int_err=%0b", req.int_err), UVM_LOW)
finish_item(req);
get_response(rsp);
`uvm_info(`gfn, "alert receiver transfer done", UVM_HIGH)
diff --git a/hw/dv/sv/alert_agent/seq_lib/alert_receiver_seq.sv b/hw/dv/sv/alert_agent/seq_lib/alert_receiver_seq.sv
index f60e0cc..50d9349 100644
--- a/hw/dv/sv/alert_agent/seq_lib/alert_receiver_seq.sv
+++ b/hw/dv/sv/alert_agent/seq_lib/alert_receiver_seq.sv
@@ -11,11 +11,6 @@
`uvm_object_utils(alert_receiver_seq)
- rand bit ping_int_err;
-
- constraint no_int_err_c {
- ping_int_err == 0;
- }
`uvm_object_new
task body();
@@ -23,12 +18,10 @@
req = REQ::type_id::create("req");
start_item(req);
`DV_CHECK_RANDOMIZE_WITH_FATAL(req,
- ping_send == 1;
- ping_int_err == local::ping_int_err;
- alert_rsp == 0;
- ack_int_err == 0;
+ r_alert_ping_send == 1;
+ r_alert_rsp == 0;
)
- `uvm_info(`gfn, $sformatf("seq_item: ping_send, ping_int_err=%0b", ping_int_err), UVM_LOW)
+ `uvm_info(`gfn, $sformatf("seq_item: ping_send, int_err=%0b", req.int_err), UVM_LOW)
finish_item(req);
get_response(rsp);
`uvm_info(`gfn, "alert receiver transfer done", UVM_HIGH)
diff --git a/hw/dv/sv/alert_agent/seq_lib/alert_sender_ping_rsp_seq.sv b/hw/dv/sv/alert_agent/seq_lib/alert_sender_ping_rsp_seq.sv
index 8bbd3a7..a7e4a28 100644
--- a/hw/dv/sv/alert_agent/seq_lib/alert_sender_ping_rsp_seq.sv
+++ b/hw/dv/sv/alert_agent/seq_lib/alert_sender_ping_rsp_seq.sv
@@ -12,21 +12,15 @@
`uvm_object_utils(alert_sender_ping_rsp_seq)
`uvm_object_new
- rand bit alert_int_err;
-
- constraint no_int_err_c {
- alert_int_err == 0;
- }
-
virtual task body();
`uvm_info(`gfn, $sformatf("starting alert receiver transfer"), UVM_HIGH)
req = REQ::type_id::create("req");
start_item(req);
`DV_CHECK_RANDOMIZE_WITH_FATAL(req,
- alert_send == 0;
- ping_rsp == 1;
- alert_int_err == local::alert_int_err;
+ s_alert_send == 0;
+ s_alert_ping_rsp == 1;
)
+ `uvm_info(`gfn, $sformatf("seq_item: ping_rsp, int_err=%0b", req.int_err), UVM_LOW)
finish_item(req);
get_response(rsp);
`uvm_info(`gfn, "alert receiver transfer done", UVM_HIGH)
diff --git a/hw/dv/sv/alert_agent/seq_lib/alert_sender_seq.sv b/hw/dv/sv/alert_agent/seq_lib/alert_sender_seq.sv
index fef108f..f5cde69 100644
--- a/hw/dv/sv/alert_agent/seq_lib/alert_sender_seq.sv
+++ b/hw/dv/sv/alert_agent/seq_lib/alert_sender_seq.sv
@@ -10,12 +10,6 @@
);
`uvm_object_utils(alert_sender_seq)
-
- rand bit alert_int_err;
-
- constraint no_int_err_c {
- alert_int_err == 0;
- }
`uvm_object_new
task body();
@@ -23,11 +17,10 @@
req = REQ::type_id::create("req");
start_item(req);
`DV_CHECK_RANDOMIZE_WITH_FATAL(req,
- alert_send == 1;
- alert_int_err == local::alert_int_err;
- ping_rsp == 0;
+ s_alert_send == 1;
+ s_alert_ping_rsp == 0;
)
- `uvm_info(`gfn, $sformatf("seq_item, alert_send=%0b", req.alert_send), UVM_LOW)
+ `uvm_info(`gfn, $sformatf("seq_item: alert_send, int_err=%0b", req.int_err), UVM_LOW)
finish_item(req);
get_response(rsp);
`uvm_info(`gfn, "alert sender transfer done", UVM_HIGH)
diff --git a/hw/dv/sv/alert_agent/seq_lib/esc_receiver_esc_rsp_seq.sv b/hw/dv/sv/alert_agent/seq_lib/esc_receiver_esc_rsp_seq.sv
new file mode 100644
index 0000000..2d49a19
--- /dev/null
+++ b/hw/dv/sv/alert_agent/seq_lib/esc_receiver_esc_rsp_seq.sv
@@ -0,0 +1,28 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// this sequence responses to escalation pins by sending the resp pins
+class esc_receiver_esc_rsp_seq extends dv_base_seq #(
+ .REQ (alert_seq_item),
+ .CFG_T (alert_agent_cfg),
+ .SEQUENCER_T (alert_sequencer)
+ );
+
+ `uvm_object_utils(esc_receiver_esc_rsp_seq)
+ `uvm_object_new
+
+ virtual task body();
+ `uvm_info(`gfn, $sformatf("starting escalator receiver transfer"), UVM_HIGH)
+ req = REQ::type_id::create("req");
+ start_item(req);
+ `DV_CHECK_RANDOMIZE_WITH_FATAL(req,
+ r_esc_rsp == 1;
+ )
+ `uvm_info(`gfn, $sformatf("seq_item: esc_rsp, int_err=%0b", req.int_err), UVM_LOW)
+ finish_item(req);
+ get_response(rsp);
+ `uvm_info(`gfn, "escalator receiver transfer done", UVM_HIGH)
+ endtask : body
+
+endclass : esc_receiver_esc_rsp_seq
diff --git a/hw/dv/sv/cip_lib/cip_base_vseq.sv b/hw/dv/sv/cip_lib/cip_base_vseq.sv
index d39ff13..0cf0c67 100644
--- a/hw/dv/sv/cip_lib/cip_base_vseq.sv
+++ b/hw/dv/sv/cip_lib/cip_base_vseq.sv
@@ -458,18 +458,4 @@
join_none
end
endtask
-
- virtual task run_ping_rsp_seq_nonblocking();
- foreach(cfg.list_of_alerts[i]) begin
- automatic string seqr_name = cfg.list_of_alerts[i];
- fork
- forever begin
- alert_sender_ping_rsp_seq ping_seq =
- alert_sender_ping_rsp_seq::type_id::create("ping_seq");
- `DV_CHECK_RANDOMIZE_FATAL(ping_seq);
- ping_seq.start(p_sequencer.alert_sequencer_h[seqr_name]);
- end
- join_none
- end
- endtask
endclass
diff --git a/hw/formal/fpv.tcl b/hw/formal/fpv.tcl
index b1d08a4..ff5a4d5 100644
--- a/hw/formal/fpv.tcl
+++ b/hw/formal/fpv.tcl
@@ -10,8 +10,7 @@
# Disabling the warning
# "parameter declared inside package XXX shall be treated as localparam".
set_message -disable VERI-2418
-check_cov -init -model {branch statement functional} \
--enable_prove_based_proof_core
+
#-------------------------------------------------------------------------
# read design
@@ -161,12 +160,10 @@
#-------------------------------------------------------------------------
# time limit set to 2 hours
get_reset_info -x_value -with_reset_pin
-prove -all -time_limit 120m
+prove -all -time_limit 24h
report
#-------------------------------------------------------------------------
# check coverage and report
#-------------------------------------------------------------------------
-check_cov -measure
-check_cov -report -type all -no_return -report_file cover.html \
- -html -force -exclude { reset waived }
+
diff --git a/hw/ip/alert_handler/dv/env/alert_handler_env.sv b/hw/ip/alert_handler/dv/env/alert_handler_env.sv
index 7ffc506..6e327e8 100644
--- a/hw/ip/alert_handler/dv/env/alert_handler_env.sv
+++ b/hw/ip/alert_handler/dv/env/alert_handler_env.sv
@@ -13,10 +13,11 @@
`uvm_component_new
alert_agent alert_host_agent[];
+ alert_agent esc_device_agent[];
function void build_phase(uvm_phase phase);
super.build_phase(phase);
-
+ // build alert agents
alert_host_agent = new[alert_pkg::NAlerts];
virtual_sequencer.alert_host_seqr_h = new[alert_pkg::NAlerts];
foreach (alert_host_agent[i]) begin
@@ -25,7 +26,15 @@
uvm_config_db#(alert_agent_cfg)::set(this,
$sformatf("alert_host_agent[%0d]", i), "cfg", cfg.alert_host_cfg[i]);
end
-
+ // build escalator agents
+ esc_device_agent = new[alert_pkg::N_ESC_SEV];
+ virtual_sequencer.esc_device_seqr_h = new[alert_pkg::N_ESC_SEV];
+ foreach (esc_device_agent[i]) begin
+ esc_device_agent[i] = alert_agent::type_id::create(
+ $sformatf("esc_device_agent[%0d]", i), this);
+ uvm_config_db#(alert_agent_cfg)::set(this,
+ $sformatf("esc_device_agent[%0d]", i), "cfg", cfg.esc_device_cfg[i]);
+ end
// get vifs
if (!uvm_config_db#(esc_en_vif)::get(this, "", "esc_en_vif", cfg.esc_en_vif)) begin
`uvm_fatal(get_full_name(), "failed to get esc_en_vif from uvm_config_db")
@@ -41,6 +50,9 @@
foreach (alert_host_agent[i]) begin
alert_host_agent[i].monitor.alert_port.connect(scoreboard.alert_fifo[i].analysis_export);
end
+ foreach (esc_device_agent[i]) begin
+ esc_device_agent[i].monitor.alert_port.connect(scoreboard.esc_fifo[i].analysis_export);
+ end
end
if (cfg.is_active) begin
foreach (alert_host_agent[i]) begin
@@ -49,6 +61,11 @@
end
end
end
+ foreach (esc_device_agent[i]) begin
+ if (cfg.esc_device_cfg[i].is_active) begin
+ virtual_sequencer.esc_device_seqr_h[i] = esc_device_agent[i].sequencer;
+ end
+ end
endfunction
endclass
diff --git a/hw/ip/alert_handler/dv/env/alert_handler_env_cfg.sv b/hw/ip/alert_handler/dv/env/alert_handler_env_cfg.sv
index 6670eaf..213a82a 100644
--- a/hw/ip/alert_handler/dv/env/alert_handler_env_cfg.sv
+++ b/hw/ip/alert_handler/dv/env/alert_handler_env_cfg.sv
@@ -8,9 +8,11 @@
esc_en_vif esc_en_vif;
entropy_vif entropy_vif;
rand alert_agent_cfg alert_host_cfg[];
+ rand alert_agent_cfg esc_device_cfg[];
`uvm_object_utils_begin(alert_handler_env_cfg)
`uvm_field_array_object(alert_host_cfg, UVM_DEFAULT)
+ `uvm_field_array_object(esc_device_cfg, UVM_DEFAULT)
`uvm_object_utils_end
`uvm_object_new
@@ -31,10 +33,16 @@
end
alert_host_cfg = new[alert_pkg::NAlerts];
+ esc_device_cfg = new[alert_pkg::N_ESC_SEV];
foreach (alert_host_cfg[i]) begin
alert_host_cfg[i] = alert_agent_cfg::type_id::create($sformatf("alert_host_cfg[%0d]", i));
alert_host_cfg[i].if_mode = dv_utils_pkg::Host;
end
+ foreach (esc_device_cfg[i]) begin
+ esc_device_cfg[i] = alert_agent_cfg::type_id::create($sformatf("esc_device_cfg[%0d]", i));
+ esc_device_cfg[i].if_mode = dv_utils_pkg::Device;
+ esc_device_cfg[i].is_alert = 0;
+ end
endfunction
endclass
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 3b2aad2..2a21e26 100644
--- a/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
+++ b/hw/ip/alert_handler/dv/env/alert_handler_scoreboard.sv
@@ -50,7 +50,7 @@
forever begin
alert_fifo[index].get(act_item);
// once the alert is received
- if (act_item.alert_type == AlertTrans && !act_item.timeout &&
+ 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;
diff --git a/hw/ip/alert_handler/dv/env/alert_handler_virtual_sequencer.sv b/hw/ip/alert_handler/dv/env/alert_handler_virtual_sequencer.sv
index d5aee2b..7402f84 100644
--- a/hw/ip/alert_handler/dv/env/alert_handler_virtual_sequencer.sv
+++ b/hw/ip/alert_handler/dv/env/alert_handler_virtual_sequencer.sv
@@ -7,6 +7,7 @@
.COV_T(alert_handler_env_cov)
);
alert_sequencer alert_host_seqr_h[];
+ alert_sequencer esc_device_seqr_h[];
`uvm_component_utils(alert_handler_virtual_sequencer)
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 da2f9c9..fcbd854 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
@@ -57,4 +57,32 @@
csr_rd(.ptr(ral.alert_cause), .value(alert_cause));
endtask
+ virtual task run_esc_rsp_seq_nonblocking();
+ foreach(cfg.esc_device_cfg[i]) begin
+ automatic int index = i;
+ fork
+ 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);
+ esc_seq.start(p_sequencer.esc_device_seqr_h[index]);
+ end
+ join_none
+ end
+ endtask
+
+ virtual task run_ping_rsp_seq_nonblocking();
+ foreach(cfg.alert_host_cfg[i]) begin
+ automatic int index = i;
+ fork
+ forever begin
+ alert_sender_ping_rsp_seq ping_seq =
+ alert_sender_ping_rsp_seq::type_id::create("ping_seq");
+ `DV_CHECK_RANDOMIZE_FATAL(ping_seq);
+ ping_seq.start(p_sequencer.alert_host_seqr_h[i]);
+ end
+ join_none
+ end
+ endtask
+
endclass : alert_handler_base_vseq
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 57f5ad9..c4b1409 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
@@ -16,6 +16,7 @@
}
task body();
+ run_esc_rsp_seq_nonblocking();
for (int i = 1; i <= num_trans; i++) begin
`DV_CHECK_RANDOMIZE_FATAL(this)
`DV_CHECK_RANDOMIZE_WITH_FATAL(ral.classa_ctrl,
diff --git a/hw/ip/alert_handler/dv/tb/tb.sv b/hw/ip/alert_handler/dv/tb/tb.sv
index 398df83..fd0134d 100644
--- a/hw/ip/alert_handler/dv/tb/tb.sv
+++ b/hw/ip/alert_handler/dv/tb/tb.sv
@@ -15,7 +15,7 @@
wire clk, rst_n;
wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
- wire [NUM_MAX_ESC_SEV-1:0] esc_en;
+ wire [NUM_MAX_ESC_SEV-1:0] esc_en;
wire entropy;
// interfaces
@@ -33,21 +33,31 @@
prim_pkg::esc_rx_t [alert_pkg::N_ESC_SEV-1:0] esc_rx;
prim_pkg::esc_tx_t [alert_pkg::N_ESC_SEV-1:0] esc_tx;
- alert_if alert_hosts_if[alert_pkg::NAlerts](.clk(clk), .rst_n(rst_n));
-
+ alert_if alert_host_if[alert_pkg::NAlerts](.clk(clk), .rst_n(rst_n));
for (genvar k = 0; k < alert_pkg::NAlerts; k++) begin : gen_alert_if
- assign alert_tx[k].alert_p = alert_hosts_if[k].alert_tx.alert_p;
- assign alert_tx[k].alert_n = alert_hosts_if[k].alert_tx.alert_n;
- assign alert_hosts_if[k].alert_rx.ack_p = alert_rx[k].ack_p;
- assign alert_hosts_if[k].alert_rx.ack_n = alert_rx[k].ack_n;
- assign alert_hosts_if[k].alert_rx.ping_p = alert_rx[k].ping_p;
- assign alert_hosts_if[k].alert_rx.ping_n = alert_rx[k].ping_n;
+ assign alert_tx[k].alert_p = alert_host_if[k].alert_tx.alert_p;
+ assign alert_tx[k].alert_n = alert_host_if[k].alert_tx.alert_n;
+ assign alert_host_if[k].alert_rx.ack_p = alert_rx[k].ack_p;
+ assign alert_host_if[k].alert_rx.ack_n = alert_rx[k].ack_n;
+ assign alert_host_if[k].alert_rx.ping_p = alert_rx[k].ping_p;
+ assign alert_host_if[k].alert_rx.ping_n = alert_rx[k].ping_n;
initial begin
uvm_config_db#(virtual alert_if)::set(null, $sformatf("*.env.alert_host_agent[%0d]", k),
- "vif", alert_hosts_if[k]);
+ "vif", alert_host_if[k]);
end
end
+ alert_if esc_device_if[alert_pkg::N_ESC_SEV](.clk(clk), .rst_n(rst_n));
+ for (genvar k = 0; k < alert_pkg::N_ESC_SEV; k++) begin : gen_esc_if
+ assign esc_rx[k].resp_p = esc_device_if[k].esc_rx.resp_p;
+ assign esc_rx[k].resp_n = esc_device_if[k].esc_rx.resp_n;
+ assign esc_device_if[k].esc_tx.esc_p = esc_tx[k].esc_p;
+ assign esc_device_if[k].esc_tx.esc_n = esc_tx[k].esc_n;
+ initial begin
+ uvm_config_db#(virtual alert_if)::set(null, $sformatf("*.env.esc_device_agent[%0d]", k),
+ "vif", esc_device_if[k]);
+ end
+ end
// main dut
alert_handler dut (
.clk_i ( clk ),
@@ -66,17 +76,6 @@
.esc_tx_o ( esc_tx )
);
- // escalation receiver duts
- for (genvar k = 0; k < alert_pkg::N_ESC_SEV; k++) begin : gen_esc_rx
- prim_esc_receiver i_prim_esc_receiver (
- .clk_i ( clk ),
- .rst_ni ( rst_n ),
- .esc_en_o ( esc_en[k] ),
- .esc_rx_o ( esc_rx[k] ),
- .esc_tx_i ( esc_tx[k] )
- );
- end
-
initial begin
// drive clk and rst_n from clk_if
clk_rst_if.set_active();