Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -1,41 +1,41 @@
// Copyright lowRISC contributors (OpenTitan project).
// 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_esc_seq_item, alert_esc_agent_cfg);
alert_esc_seq_item r_alert_ping_send_q[$], r_alert_rsp_q[$], r_esc_rsp_q[$],
s_alert_send_q[$], s_alert_ping_rsp_q[$];
// Virtual base class used for alert_sender_driver and alert_receiver_driver

`uvm_component_utils(alert_esc_base_driver)
virtual class alert_base_driver extends dv_base_driver#(alert_esc_seq_item, alert_esc_agent_cfg);
alert_esc_seq_item r_alert_ping_send_q[$], r_alert_rsp_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.

I don't know if we have a rule in our coding style, but I never declare multiple variables on the same line as it was forbidden in my previous company, and I think it's a good practice. The main reason was to avoid to change a signal type for one and which doesn't applies to the others (by negligence), diff are easier to track and we can add comments on the same line.

PS: I have checked and it's also part of Doulos guidelines -> look for "Have only one declaration or statement per line"

s_alert_send_q[$], s_alert_ping_rsp_q[$];

extern function new (string name, uvm_component parent);
// drive trans received from sequencer

// Take items from the sequencer and drive them. This implements a task from dv_base_driver.
extern virtual task get_and_drive();
extern virtual task drive_req();
extern virtual task get_req();

endclass : alert_esc_base_driver
// Monitor seq_item_port and add the items to the various queues
//
// This is run by get_and_drive.
extern local task get_req();

// Drive items that have been added to the various queues by get_req
//
// This should run forever and is started by get_and_drive.
pure virtual task drive_req();
endclass

function alert_esc_base_driver::new (string name, uvm_component parent);
function alert_base_driver::new (string name, uvm_component parent);
super.new(name, parent);
endfunction : new

task alert_esc_base_driver::get_and_drive();
task alert_base_driver::get_and_drive();
fork
get_req();
drive_req();
join_none
endtask : get_and_drive
join
endtask
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.

Nit: that follows one of our past discussion, I'd not remove the end of method labels as my preference would be to have it particularly when the rest of the class follows this


task alert_esc_base_driver::drive_req();
`uvm_fatal(`gfn, "this is implemented as pure virtual task - please extend")
endtask : drive_req

task alert_esc_base_driver::get_req();
task alert_base_driver::get_req();
@(posedge cfg.vif.rst_n);
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.

Here isn't it best to point at a in_reset internal signal?

forever begin
alert_esc_seq_item req_clone;
Expand All @@ -45,12 +45,16 @@ task alert_esc_base_driver::get_req();
// receiver mode
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);

if (req.r_esc_rsp) begin
`uvm_error(get_full_name(), "Alert driver cannot drive an esc item")
end

`uvm_info(`gfn, $sformatf({"Driver received item (after pushing): req.r_alert_ping_send=%0d",
" | req.r_alert_rsp=%0d | req.r_esc_rsp=%0d"},
req.r_alert_ping_send, req.r_alert_rsp, req.r_esc_rsp), UVM_DEBUG)
" | req.r_alert_rsp=%0d"},
req.r_alert_ping_send, req.r_alert_rsp), UVM_DEBUG)
end
endtask : get_req
2 changes: 1 addition & 1 deletion hw/dv/sv/alert_esc_agent/alert_esc_agent.core
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ filesets:
- lowrisc:prim:all:0.1
- lowrisc:dv:dv_lib
files:
- alert_base_driver.sv: {is_include_file: true}
- alert_esc_if.sv
- alert_esc_probe_if.sv
- alert_esc_agent_pkg.sv
- alert_esc_agent_cfg.sv: {is_include_file: true}
- alert_esc_agent.sv: {is_include_file: true}
- alert_esc_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}
Expand Down
2 changes: 1 addition & 1 deletion hw/dv/sv/alert_esc_agent/alert_esc_agent.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// ---------------------------------------------
class alert_esc_agent extends dv_base_agent#(
.CFG_T (alert_esc_agent_cfg),
.DRIVER_T (alert_esc_base_driver),
.DRIVER_T (dv_base_driver#(alert_esc_seq_item, alert_esc_agent_cfg)),
.SEQUENCER_T (alert_esc_sequencer),
.MONITOR_T (alert_esc_base_monitor),
.COV_T (alert_esc_agent_cov)
Expand Down
2 changes: 1 addition & 1 deletion hw/dv/sv/alert_esc_agent/alert_esc_agent_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ package alert_esc_agent_pkg;
`include "alert_esc_seq_item.sv"
`include "alert_esc_agent_cfg.sv"
`include "alert_esc_agent_cov.sv"
`include "alert_esc_base_driver.sv"
`include "alert_base_driver.sv"
`include "alert_sender_driver.sv"
`include "alert_receiver_driver.sv"
`include "esc_sender_driver.sv"
Expand Down
2 changes: 1 addition & 1 deletion hw/dv/sv/alert_esc_agent/alert_receiver_driver.sv
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// A driver that receives alerts. This is used in alert_esc_agent when configured in "device mode"
// (so the dut is a device and the agent is expecting to receive alerts and send occasional pings)
class alert_receiver_driver extends alert_esc_base_driver;
class alert_receiver_driver extends alert_base_driver;
`uvm_component_utils(alert_receiver_driver)

bit working_on_alert;
Expand Down
2 changes: 1 addition & 1 deletion hw/dv/sv/alert_esc_agent/alert_sender_driver.sv
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// ---------------------------------------------
// Alert_handler sender driver
// ---------------------------------------------
class alert_sender_driver extends alert_esc_base_driver;
class alert_sender_driver extends alert_base_driver;

`uvm_component_utils(alert_sender_driver)

Expand Down
26 changes: 13 additions & 13 deletions hw/dv/sv/alert_esc_agent/esc_receiver_driver.sv
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
// 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;
// Escalation receiver driver

`uvm_component_utils(esc_receiver_driver)
class esc_receiver_driver extends dv_base_driver#(alert_esc_seq_item, alert_esc_agent_cfg);

`uvm_component_utils(esc_receiver_driver)

// Set by esc_ping_detector if it sees a single-cycle pulse on esc_p/esc_n. If set, the receiver
// will drive a 1010 pattern on resp_p/resp_n for a while in drive_esc_resp (stopping if it
Expand All @@ -22,10 +20,11 @@ class esc_receiver_driver extends alert_esc_base_driver;
// Overridden from dv_base_driver.
extern virtual task reset_signals();

// Run rsp_escalator and esc_ping_detector. Does not terminate.
// This task runs forever. It works by running rsp_escalator (which consumes and drives items from
// seq_item_port) and esc_ping_detector (which responds to ping requests).
//
// Overridden from alert_esc_base_driver.
extern virtual task drive_req();
// Overridden from dv_base_driver.
extern virtual task get_and_drive();

// Run forever, detect single-cycle escalation requests. These are ping requests. When one
// happens, set is_ping, which tells drive_esc_resp to send the 1010... pattern.
Expand Down Expand Up @@ -76,12 +75,12 @@ task esc_receiver_driver::reset_signals();
end
endtask : reset_signals

task esc_receiver_driver::drive_req();
task esc_receiver_driver::get_and_drive();
fork
rsp_escalator();
esc_ping_detector();
join
endtask : drive_req
endtask : get_and_drive

task esc_receiver_driver::esc_ping_detector();
forever begin
Expand Down Expand Up @@ -115,11 +114,12 @@ endtask : esc_ping_detector

task esc_receiver_driver::rsp_escalator();
forever begin
alert_esc_seq_item req, rsp;
wait(r_esc_rsp_q.size() > 0 && !under_reset);
req = r_esc_rsp_q.pop_front();
alert_esc_seq_item rsp;

seq_item_port.get(req);
`downcast(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
Expand Down
33 changes: 11 additions & 22 deletions hw/dv/sv/alert_esc_agent/esc_sender_driver.sv
Original file line number Diff line number Diff line change
@@ -1,54 +1,43 @@
// Copyright lowRISC contributors (OpenTitan project).
// 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;
// Escalation sender driver

class esc_sender_driver extends dv_base_driver#(alert_esc_seq_item, alert_esc_agent_cfg);
`uvm_component_utils(esc_sender_driver)


extern function new (string name, uvm_component parent);
extern virtual task reset_signals();
extern virtual task get_and_drive();
extern virtual task drive_esc();
extern virtual task do_reset();

extern local task reset_esc();
endclass : esc_sender_driver

function esc_sender_driver::new (string name, uvm_component parent);
super.new(name, parent);
endfunction : new

task esc_sender_driver::reset_signals();
do_reset();
wait(cfg.vif.rst_n !== 1'b1);
forever begin
@(negedge cfg.vif.rst_n);
under_reset = 1;
do_reset();
@(posedge cfg.vif.rst_n);
reset_esc();
wait(cfg.vif.rst_n === 1'b1);
under_reset = 0;

wait(cfg.vif.rst_n !== 1'b1);
end
endtask : reset_signals

task esc_sender_driver::get_and_drive();
// LC_CTRL uses virtual interface to directly drive escalation requests.
// Other escalation handshakes are checked in prim_esc direct sequence.
// So the following task is not implemented.
drive_esc();
endtask : get_and_drive

task esc_sender_driver::drive_esc();
// LC_CTRL uses virtual interface to directly drive escalation requests.
// Other escalation handshakes are checked in prim_esc direct sequence.
// So this task is not implemented.
wait(!under_reset);
endtask : drive_esc
endtask : get_and_drive

task esc_sender_driver::do_reset();
task esc_sender_driver::reset_esc();
cfg.vif.esc_tx_int.esc_p <= 1'b0;
cfg.vif.esc_tx_int.esc_n <= 1'b1;
endtask : do_reset
endtask : reset_esc
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,12 @@ class ${module_instance_name}_base_vseq extends cip_base_vseq #(
`DV_CHECK_RANDOMIZE_WITH_FATAL(esc_seq, int_err == esc_int_err; standalone_int_err == 0;
ping_timeout == ping_timeout_err;)
esc_seq.start(p_sequencer.esc_device_seqr_h[index]);

// The sequence has finished, which either means that we have seen an escalation and sent
// a response, or it means that a reset has happened. Watch the agent's configuration to
// wait until it is out of reset before starting a sequence to respond to the next
// escalation.
wait(!cfg.esc_device_cfg[index].in_reset);
end
join_none
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,12 @@ class alert_handler_base_vseq extends cip_base_vseq #(
`DV_CHECK_RANDOMIZE_WITH_FATAL(esc_seq, int_err == esc_int_err; standalone_int_err == 0;
ping_timeout == ping_timeout_err;)
esc_seq.start(p_sequencer.esc_device_seqr_h[index]);

// The sequence has finished, which either means that we have seen an escalation and sent
// a response, or it means that a reset has happened. Watch the agent's configuration to
// wait until it is out of reset before starting a sequence to respond to the next
// escalation.
wait(!cfg.esc_device_cfg[index].in_reset);
end
join_none
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,12 @@ class alert_handler_base_vseq extends cip_base_vseq #(
`DV_CHECK_RANDOMIZE_WITH_FATAL(esc_seq, int_err == esc_int_err; standalone_int_err == 0;
ping_timeout == ping_timeout_err;)
esc_seq.start(p_sequencer.esc_device_seqr_h[index]);

// The sequence has finished, which either means that we have seen an escalation and sent
// a response, or it means that a reset has happened. Watch the agent's configuration to
// wait until it is out of reset before starting a sequence to respond to the next
// escalation.
wait(!cfg.esc_device_cfg[index].in_reset);
end
join_none
end
Expand Down
Loading