mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 22:07:43 -04:00
Update lowrisc_ip to lowRISC/opentitan@3f35d4e4
Update code from upstream repository https://github.com/lowRISC/opentitan to revision 3f35d4e42757aeed3f9699d7965f20af41d9d36f * [dv] Initial flash_ctrl DV testbench (Srikrishna Iyer) * [dv] Cleanup Xcelium warning: unconnected port (Srikrishna Iyer) * [dv] Cleanup Xcelium warning: default arg (Srikrishna Iyer) * [dv] Clean up for phase_read_to_end (Weicai Yang) * [DV] Remove urandom from task port (Dawid Zimonczyk) * [doc] Update lint commands in readme (Michael Schaffner) * [dv] Refactor watchdog_ok_to_end (Srikrishna Iyer) Signed-off-by: Philipp Wagner <phw@lowrisc.org>
This commit is contained in:
parent
dd39ec0c91
commit
b95ff21c28
10 changed files with 90 additions and 93 deletions
2
vendor/lowrisc_ip.lock.hjson
vendored
2
vendor/lowrisc_ip.lock.hjson
vendored
|
@ -9,6 +9,6 @@
|
|||
upstream:
|
||||
{
|
||||
url: https://github.com/lowRISC/opentitan
|
||||
rev: 249b4c316cd6626d13e17edd8a52ca60c004af96
|
||||
rev: 3f35d4e42757aeed3f9699d7965f20af41d9d36f
|
||||
}
|
||||
}
|
||||
|
|
10
vendor/lowrisc_ip/common_ifs/clk_rst_if.sv
vendored
10
vendor/lowrisc_ip/common_ifs/clk_rst_if.sv
vendored
|
@ -172,11 +172,13 @@ interface clk_rst_if #(
|
|||
// 2 - async assert, async dessert
|
||||
// 3 - clk gated when reset asserted
|
||||
// Note: for power on reset, please ensure pre_reset_dly_clks is set to 0
|
||||
task automatic apply_reset(int pre_reset_dly_clks = 0,
|
||||
int reset_width_clks = $urandom_range(4, 20),
|
||||
int post_reset_dly_clks = 0,
|
||||
int rst_n_scheme = 1);
|
||||
// TODO #2338 issue workaround - $urandom call moved from default argument value to function body
|
||||
task automatic apply_reset(int pre_reset_dly_clks = 0,
|
||||
integer reset_width_clks = 'x,
|
||||
int post_reset_dly_clks = 0,
|
||||
int rst_n_scheme = 1);
|
||||
int dly_ps;
|
||||
if ($isunknown(reset_width_clks)) reset_width_clks = $urandom_range(4, 20);
|
||||
dly_ps = $urandom_range(0, clk_period_ps);
|
||||
wait_clks(pre_reset_dly_clks);
|
||||
case (rst_n_scheme)
|
||||
|
|
115
vendor/lowrisc_ip/dv_lib/dv_base_monitor.sv
vendored
115
vendor/lowrisc_ip/dv_lib/dv_base_monitor.sv
vendored
|
@ -10,13 +10,9 @@ class dv_base_monitor #(type ITEM_T = uvm_sequence_item,
|
|||
CFG_T cfg;
|
||||
COV_T cov;
|
||||
|
||||
// extended monitor needs to drive ok_to_end = 0 when bus is busy, set to 1 when it's not busy
|
||||
// Indicates activity on the interface, driven only within the `monitor_ready_to_end()` task.
|
||||
protected bit ok_to_end = 1;
|
||||
|
||||
// make sure at least we add ok_to_end_delay_ns once and invoke monitor_ready_to_end once
|
||||
// after enter phase_ready_to_end
|
||||
protected bit watchdog_done;
|
||||
|
||||
// Analysis port for the collected transfer.
|
||||
uvm_analysis_port #(ITEM_T) analysis_port;
|
||||
|
||||
|
@ -38,64 +34,73 @@ class dv_base_monitor #(type ITEM_T = uvm_sequence_item,
|
|||
`uvm_fatal(`gfn, "this method is not supposed to be called directly!")
|
||||
endtask
|
||||
|
||||
// UVM callback which is invoked during phase sequencing.
|
||||
virtual function void phase_ready_to_end(uvm_phase phase);
|
||||
if (phase.is(uvm_run_phase::get())) begin
|
||||
if (watchdog_done) fork
|
||||
monitor_ready_to_end();
|
||||
join_none
|
||||
if (!ok_to_end || !watchdog_done) begin
|
||||
phase.raise_objection(this, $sformatf("%s objection raised", `gfn));
|
||||
`uvm_info(`gfn, $sformatf("Raised objection, because ok_to_end: %0b, watchdog_done: %0b",
|
||||
ok_to_end, watchdog_done), UVM_MEDIUM)
|
||||
|
||||
fork
|
||||
begin
|
||||
// wait until ok_to_end is set plus the delay of ok_to_end_delay_ns
|
||||
watchdog_ok_to_end();
|
||||
phase.drop_objection(this, $sformatf("%s objection dropped", `gfn));
|
||||
`uvm_info(`gfn, $sformatf("Dropped objection"), UVM_MEDIUM)
|
||||
end
|
||||
join_none;
|
||||
end
|
||||
end
|
||||
if (!phase.is(uvm_run_phase::get())) return;
|
||||
fork
|
||||
monitor_ready_to_end();
|
||||
watchdog_ok_to_end(phase);
|
||||
join_none
|
||||
endfunction
|
||||
|
||||
// This watchdog will wait for ok_to_end_delay_ns while checking for any
|
||||
// traffic on the bus during this period.
|
||||
// If traffic is seen before ok_to_end_delay_ns, the watchdog will keep
|
||||
// repeating this process until the traffic has stopped.
|
||||
virtual task watchdog_ok_to_end();
|
||||
fork
|
||||
begin : isolation_fork
|
||||
bit watchdog_reset;
|
||||
// Ensures that ok_to_end when asserted, stays asserted for 1 ok_to_end_delay_ns period.
|
||||
//
|
||||
// If ok_to_end de-asserts before the watchdog expires, it waits for it to assert again
|
||||
// and restarts the timer. This ensures that there is sufficient drain time to allow the
|
||||
// simulation to end gracefully. It raises and drops the objection at the appropriate times.
|
||||
virtual task watchdog_ok_to_end(uvm_phase run_phase);
|
||||
bit objection_raised;
|
||||
bit watchdog_done;
|
||||
uint watchdog_restart_count = 1;
|
||||
|
||||
fork
|
||||
forever begin
|
||||
// check the bus interface for any traffic. If any, extend timer for one more
|
||||
// ok_to_end_delay_ns
|
||||
@(ok_to_end or watchdog_reset);
|
||||
if (!ok_to_end && !watchdog_reset) watchdog_reset = 1;
|
||||
end
|
||||
forever begin
|
||||
#(cfg.ok_to_end_delay_ns * 1ns);
|
||||
if (!watchdog_reset) begin
|
||||
break;
|
||||
end else begin
|
||||
`uvm_info(`gfn, "Resetting phase watchdog timer", UVM_HIGH)
|
||||
watchdog_reset = 0;
|
||||
forever begin
|
||||
if (!objection_raised) begin
|
||||
`uvm_info(`gfn, "watchdog_ok_to_end: raising objection", UVM_MEDIUM)
|
||||
run_phase.raise_objection(this, {`gfn, " objection raised"});
|
||||
objection_raised = 1'b1;
|
||||
end
|
||||
|
||||
// Start the timer only when ok_to_end is asserted.
|
||||
wait(ok_to_end);
|
||||
`uvm_info(`gfn, $sformatf("watchdog_ok_to_end: starting the timer (count: %0d)",
|
||||
watchdog_restart_count++), UVM_MEDIUM)
|
||||
fork
|
||||
begin: isolation_fork
|
||||
fork
|
||||
begin
|
||||
watchdog_done = 1'b0;
|
||||
#(cfg.ok_to_end_delay_ns * 1ns);
|
||||
watchdog_done = 1'b1;
|
||||
end
|
||||
end
|
||||
join_any;
|
||||
disable fork;
|
||||
@(ok_to_end);
|
||||
join_any
|
||||
disable fork;
|
||||
end: isolation_fork
|
||||
join
|
||||
|
||||
watchdog_done = 1;
|
||||
end : isolation_fork
|
||||
join
|
||||
// The #0 delay ensures that we sample the stabilized value of ok_to_end in the condition
|
||||
// below in case it toggles more than once in the same simulation time-step.
|
||||
#0;
|
||||
|
||||
// If ok_to_end stayed high throughout the watchdog timer expiry, then drop the objection.
|
||||
if (ok_to_end && watchdog_done) begin
|
||||
`uvm_info(`gfn, "watchdog_ok_to_end: dropping objection", UVM_MEDIUM)
|
||||
run_phase.drop_objection(this, {`gfn, " objection dropped"});
|
||||
objection_raised = 1'b0;
|
||||
|
||||
// Wait for ok_to_end to de-assert again in future.
|
||||
wait(!ok_to_end);
|
||||
end
|
||||
end
|
||||
endtask
|
||||
|
||||
// this task will be invoked as non-blocking thread when phase first enters phase_ready_to_end
|
||||
// extended class can override this task to update ok_to_end
|
||||
// Asserts/de-asserts ok_to_end to indicate bus activity.
|
||||
//
|
||||
// This task is invoked in a forked thread within `phase_ready_to_end()`, which is callback
|
||||
// invoked by UVM at the end of the phase. The forked thread does not join. Hence, the extended
|
||||
// monitor needs to override this function and assert ok_to_end based on the activity on the bus
|
||||
// (assert it when idle, de-assert when its not) in a forever loop.
|
||||
virtual task monitor_ready_to_end();
|
||||
endtask
|
||||
endclass
|
||||
|
||||
endclass
|
||||
|
|
|
@ -13,7 +13,8 @@ class dv_base_reg_block extends uvm_reg_block;
|
|||
endfunction
|
||||
|
||||
// provide build function to supply base addr
|
||||
virtual function void build(uvm_reg_addr_t base_addr, csr_utils_pkg::csr_excl_item csr_excl);
|
||||
virtual function void build(uvm_reg_addr_t base_addr,
|
||||
csr_utils_pkg::csr_excl_item csr_excl = null);
|
||||
`uvm_fatal(`gfn, "this method is not supposed to be called directly!")
|
||||
endfunction
|
||||
|
||||
|
|
12
vendor/lowrisc_ip/dv_lib/dv_base_scoreboard.sv
vendored
12
vendor/lowrisc_ip/dv_lib/dv_base_scoreboard.sv
vendored
|
@ -45,18 +45,6 @@ class dv_base_scoreboard #(type RAL_T = dv_base_reg_block,
|
|||
end
|
||||
endtask
|
||||
|
||||
// raise / drop objections based on certain events
|
||||
virtual function void process_objections(bit raise);
|
||||
if (raise && !obj_raised) begin
|
||||
m_current_phase.raise_objection(this, $sformatf("%s objection raised", `gfn));
|
||||
obj_raised = 1'b1;
|
||||
end
|
||||
else if (!raise && obj_raised) begin
|
||||
m_current_phase.drop_objection(this, $sformatf("%s objection dropped", `gfn));
|
||||
obj_raised = 1'b0;
|
||||
end
|
||||
endfunction
|
||||
|
||||
virtual function void reset(string kind = "HARD");
|
||||
// reset the ral model
|
||||
if (cfg.has_ral) ral.reset(kind);
|
||||
|
|
19
vendor/lowrisc_ip/lint/doc/README.md
vendored
19
vendor/lowrisc_ip/lint/doc/README.md
vendored
|
@ -74,15 +74,17 @@ In this example this would be `lint/aes.waiver` for AscentLint and `lint/aes.vlt
|
|||
In order to manually run lint on a specific block, make sure AscentLint is properly installed and step into the `hw/lint` folder.
|
||||
The makefile in that folder contains all targets that can be manually invoked.
|
||||
For example, to run lint on AES, do:
|
||||
```
|
||||
make ip-aes_lint
|
||||
```console
|
||||
$ cd $REPO_TOP/hw/lint
|
||||
$ make ip-aes_lint
|
||||
```
|
||||
This run will exit with PASSED status on the command line if there are no lint errors or warnings.
|
||||
Otherwise it will exit with ERROR status, in which case you can get more information by running
|
||||
```
|
||||
make clean
|
||||
make ip-aes_lint
|
||||
make report
|
||||
```console
|
||||
$ cd $REPO_TOP/hw/lint
|
||||
$ make clean
|
||||
$ make ip-aes_lint
|
||||
$ make report
|
||||
```
|
||||
In order to build all lint targets and produce a summary report, the `make all` target can be invoked.
|
||||
For more detailed information on a particular lint run you can inspect the tool output inside the build folder that is created by FuseSoC.
|
||||
|
@ -91,8 +93,9 @@ Note that all AscentLint targets have a Verilator and Verible counterparts that
|
|||
This enables designers without access to AscentLint to iterate with open-source tools before making their first Pull Request.
|
||||
|
||||
For batch regressions we have integrated this flow into the `dvsim` tool, which can be invoked as follows from the root of the project repository:
|
||||
```
|
||||
util/dvsim.py hw/top_earlgrey/lint/ascentlint/top_earlgrey_lint_cfgs.hjson --tool "ascentlint" --purge -mp 1
|
||||
```console
|
||||
$ cd $REPO_TOP
|
||||
$ util/dvsim/dvsim.py hw/top_earlgrey/lint/top_earlgrey_lint_cfgs.hjson --tool ascentlint --purge -mp 1
|
||||
```
|
||||
where the `top_earlgrey_lint_cfgs.hjson` file contains all the lint targets to be run in that regression (currently all available comportable IPs and the top-level are run).
|
||||
The `purge` option ensures that the scratch directory is fully erased before starting the build, and `mp 1` sets the number of parallel workers to one (should be set depending on your licensing situation).
|
||||
|
|
3
vendor/lowrisc_ip/uvmdvgen/base_test.sv.tpl
vendored
3
vendor/lowrisc_ip/uvmdvgen/base_test.sv.tpl
vendored
|
@ -23,10 +23,9 @@ class ${name}_base_test extends dv_base_test #(
|
|||
super.build_phase(phase);
|
||||
cfg.has_ral = 1'b0;
|
||||
endfunction
|
||||
% endif
|
||||
|
||||
% endif
|
||||
// the base class also looks up UVM_TEST_SEQ plusarg to create and run that seq in
|
||||
// the run_phase; as such, nothing more needs to be done
|
||||
|
||||
endclass : ${name}_base_test
|
||||
|
||||
|
|
1
vendor/lowrisc_ip/uvmdvgen/sim_cfg.hjson.tpl
vendored
1
vendor/lowrisc_ip/uvmdvgen/sim_cfg.hjson.tpl
vendored
|
@ -77,4 +77,3 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
|
3
vendor/lowrisc_ip/uvmdvgen/tb.sv.tpl
vendored
3
vendor/lowrisc_ip/uvmdvgen/tb.sv.tpl
vendored
|
@ -14,6 +14,7 @@ module tb;
|
|||
`include "dv_macros.svh"
|
||||
|
||||
wire clk, rst_n;
|
||||
wire devmode;
|
||||
% if is_cip:
|
||||
% if has_interrupts:
|
||||
wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
|
||||
|
@ -34,7 +35,7 @@ module tb;
|
|||
// TODO: declare alert interfaces according to the list_of_alerts
|
||||
alert_if alert_names(.clk(clk), .rst_n(rst_n))
|
||||
% endif
|
||||
pins_if #(1) devmode_if();
|
||||
pins_if #(1) devmode_if(devmode);
|
||||
tl_if tl_if(.clk(clk), .rst_n(rst_n));
|
||||
% endif
|
||||
% for agent in env_agents:
|
||||
|
|
15
vendor/lowrisc_ip/uvmdvgen/testplan.hjson.tpl
vendored
15
vendor/lowrisc_ip/uvmdvgen/testplan.hjson.tpl
vendored
|
@ -11,16 +11,15 @@
|
|||
entries: [
|
||||
{
|
||||
name: sanity
|
||||
desc: '''**Goal**: Basic sanity test acessing a major datapath in ${name.upper()}.
|
||||
desc: '''
|
||||
Basic sanity test acessing a major datapath within the ${name}.
|
||||
|
||||
**Stimulus**: Describe the stimulus procedure.
|
||||
**Stimulus**:
|
||||
- TBD
|
||||
|
||||
**Checks**": Describe the self-check procedure.
|
||||
- add bullets as needed
|
||||
- second bullet<br>
|
||||
describe second bullet
|
||||
|
||||
Start a new paragraph.'''
|
||||
**Checks**:
|
||||
- TBD
|
||||
'''
|
||||
milestone: V1
|
||||
tests: ["${name}_sanity"]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue