Update lowrisc_ibex to lowRISC/ibex@ae547c8
Update code from upstream repository
https://github.com/lowRISC/ibex.git to revision
ae547c8d3010d86ef7afdee900d461616c3cb414
* [top_pkg] Fix style lint warnings (Michael Schaffner)
* [ibex/dv] Add clocking blocks to Ibex interfaces (Udi)
* Add a stress_all_with_reset ICache test (Rupert Swarbrick)
* Invalidate in an ICache sequence after a change to mem_err_shift
(Rupert Swarbrick)
* Fix ICache caching window test with combination sequences (Rupert
Swarbrick)
* Add ibex_icache_stress_all test (Rupert Swarbrick)
* Tidy up properly after overriding class in ICache back_line_seq
(Rupert Swarbrick)
* Remove empty tasks from ibex_icache_base_vseq.sv (Rupert Swarbrick)
* Use dv_base_vseq's num_trans field rather than making our own
(Rupert Swarbrick)
* Control core sequence's transaction count from top in ICache tests
(Rupert Swarbrick)
* Remove ibex_icache_sanity_vseq (Rupert Swarbrick)
* Configure ICache mem_error tests from the vseq (not a test class)
(Rupert Swarbrick)
* Pass mem_err_shift to the ICache memory model on each error check
(Rupert Swarbrick)
* Configure ICache ECC tests just from the vseq (not a test class)
(Rupert Swarbrick)
* [rtl] disable clock between reset and fetch_enable_i (Bert Pieters)
* Add some basic protocol checking to the icache's RAM interface
(Rupert Swarbrick)
* Enable ICache ECC in the way dvsim.py requires (Rupert Swarbrick)
* Update lec_sv2v.sh (NilsGraf)
* Update lec_sv2v.sh (NilsGraf)
* Update lec_sv2v.do (NilsGraf)
* Add LEC script to formally verify sv2v translation (Nils Graf)
* [dv/ibex] Update riscv_core_setting to match latest version of
riscv-dv (Udi)
* Correct window_width calculation in ICache UVM scoreboard (Rupert
Swarbrick)
* Fix ordering in ICache core monitor start-up (Rupert Swarbrick)
* Correct "cancelled_valid" sequence in ICache UVM core coverage
(Rupert Swarbrick)
* Allow ready & branch in ICache UVM tests (Rupert Swarbrick)
* Weight branches in icache tests to favour edges of address space
(Rupert Swarbrick)
* Update google_riscv-dv to google/riscv-dv@6cf6b4f (Udi)
* Fix documentation markup for tracer (Philipp Wagner)
* [rtl] Remove use of `define in decoder (Bert Pieters)
* Increase priority of failure messages in ICache scoreboard (Rupert
Swarbrick)
* Fix verbosity in ECC UVM driver (Rupert Swarbrick)
* [dv] Fix DUT probe IF paths (Tom Roberts)
* Add ECC agents to ICache DV plan document (Rupert Swarbrick)
* Define an "ECC agent" for icache testing and a test that uses it
(Rupert Swarbrick)
* Add and use a 'badbit' RAM for ICache tests (Rupert Swarbrick)
* Enable ECC in ICache tests (Rupert Swarbrick)
* Drive the branch_spec line in ICache UVM tests (Rupert Swarbrick)
* [ibex/dv] add Questa support (Bert Pieters)
* Simplify timestamps in ICache tests (Rupert Swarbrick)
* Update lowrisc_ip to lowRISC/opentitan@c91b50f3 (Rupert Swarbrick)
* [rtl] Simplify I$ ECC error handling (Tom Roberts)
* [rtl] Use outer generate loop for latch RF (Greg Chadwick)
* [doc] Add top-level status table (Tom Roberts)
* [configs] Add a maxperf config (Tom Roberts)
* [rtl] Use gated clock for wb_stage and rf (Greg Chadwick)
* [rtl] Use generate loop in FF register file (Greg Chadwick)
Signed-off-by: Philipp Wagner <phw@lowrisc.org>
diff --git a/hw/vendor/lowrisc_ibex/README.md b/hw/vendor/lowrisc_ibex/README.md
index c385c59..e840e7b 100644
--- a/hw/vendor/lowrisc_ibex/README.md
+++ b/hw/vendor/lowrisc_ibex/README.md
@@ -7,17 +7,39 @@
<p align="center"><img src="doc/images/blockdiagram.svg" width="650"></p>
-Ibex offers several configuration parameters to meet the needs of various application scenarios.
-The options include two different choices for the architecture of the multiplier and divider unit,
-as well as the possibility to drop the support for the "M" extension completely. In addition, the
-"E" extension can be enabled when opting for a minimum-area configuration.
-
This core was initially developed as part of the [PULP platform](https://www.pulp-platform.org)
under the name "Zero-riscy" \[[1](https://doi.org/10.1109/PATMOS.2017.8106976)\], and has been
contributed to [lowRISC](https://www.lowrisc.org) who maintains it and develops it further. It is
under active development, with further code cleanups, feature additions, and test and verification
planned for the future.
+## Configuration
+
+Ibex offers several configuration parameters to meet the needs of various application scenarios.
+The options include different choices for the architecture of the multiplier unit, as well as a range of performance and security features.
+The table below indicates performance, area and verification status for a few selected configurations.
+These are configurations on which lowRISC is focusing for performance evaluation and design verification (see [supported configs](ibex_configs.yaml)).
+
+| Config | "small" | "maxperf" | "maxperf-pmp-bm" |
+| ------ | ------- | --------- | ---------------- |
+| Features | RV32IMC, 3 cycle mult | RV32IMC, 1 cycle mult, Branch target ALU, Writeback stage | RV32IMCB, 1 cycle mult, Branch target ALU, Writeback stage, 16 PMP regions |
+| Performance (Coremark/MHz) | 2.44 | 3.09 | 3.09 |
+| Area - Yosys (kGE) | 33.15 | 39.03 | 63.32 |
+| Area - Commercial (estimated kGE) | ~27 | ~31 | ~50 |
+| Verification status | Green | Amber | Amber |
+
+Notes:
+
+* Performance numbers are based on Cormark running on the Ibex Simple System [platform](examples/simple_system/README.md).
+ Note that Coremark was compiled without support for the B extension.
+* Yosys synthesis area numbers are based on the Ibex basic synthesis [flow](syn/README.md).
+* Commercial synthesis area numbers are a rough estimate of what might be achievable with a commercial synthesis flow and technology library.
+* Verification status is a rough guide to the overall maturity of a particular configuration.
+ Green indicates that verification is close to complete.
+ Amber indicates that some verification has been performed, but the configuration is still experimental.
+ Red indicates a new configuration with minimal/no verification.
+ Users must make their own assessment of verification readiness for any tapeout.
+
## Documentation
The Ibex user manual can be
diff --git a/hw/vendor/lowrisc_ibex/doc/tracer.rst b/hw/vendor/lowrisc_ibex/doc/tracer.rst
index 9e87950..4ba2610 100644
--- a/hw/vendor/lowrisc_ibex/doc/tracer.rst
+++ b/hw/vendor/lowrisc_ibex/doc/tracer.rst
@@ -26,11 +26,14 @@
3. **PC**: The program counter
4. **Instr**: The executed instruction (base 16).
32 bit wide instructions (8 hex digits) are uncompressed instructions, 16 bit wide instructions (4 hex digits) are compressed instructions.
-5. **Decoded instruction**: The decoded (disassembled) instruction in a format equal to what objdump produces when calling it like ``objdump -Mnumeric -Mno-aliases -D``.
+5. **Decoded instruction**:
+ The decoded (disassembled) instruction in a format equal to what objdump produces when calling it like ``objdump -Mnumeric -Mno-aliases -D``.
+
- Unsigned numbers are given in hex (prefixed with ``0x``), signed numbers are given as decimal numbers.
- Numeric register names are used (e.g. ``x1``).
- Symbolic CSR names are used.
- Jump/branch targets are given as absolute address if possible (PC + immediate).
+
6. **Register and memory contents**: For all accessed registers, the value before and after the instruction execution is given. Writes to registers are indicated as ``registername=value``, reads as ``registername:value``. For memory accesses, the address and the loaded and stored data are given.
.. code-block:: text
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv
index df08595..bf8659c 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf.sv
@@ -2,10 +2,13 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
-interface ibex_mem_intf#(parameter int ADDR_WIDTH = 32,
- parameter int DATA_WIDTH = 32);
+interface ibex_mem_intf#(
+ parameter int ADDR_WIDTH = 32,
+ parameter int DATA_WIDTH = 32
+) (
+ input clk
+);
- logic clock;
logic reset;
logic request;
logic grant;
@@ -17,4 +20,51 @@
logic [DATA_WIDTH-1:0] rdata;
logic error;
+ clocking host_driver_cb @(posedge clk);
+ input reset;
+ output request;
+ input grant;
+ output addr;
+ output we;
+ output be;
+ input rvalid;
+ output wdata;
+ input rdata;
+ input error;
+ endclocking
+
+ clocking device_driver_cb @(posedge clk);
+ input reset;
+ input request;
+ output grant;
+ input addr;
+ input we;
+ input be;
+ output rvalid;
+ input wdata;
+ output rdata;
+ output error;
+ endclocking
+
+ clocking monitor_cb @(posedge clk);
+ input reset;
+ input request;
+ input grant;
+ input addr;
+ input we;
+ input be;
+ input rvalid;
+ input wdata;
+ input rdata;
+ input error;
+ endclocking
+
+ task automatic wait_clks(input int num);
+ repeat (num) @(posedge clk);
+ endtask
+
+ task automatic wait_neg_clks(input int num);
+ repeat (num) @(negedge clk);
+ endtask
+
endinterface : ibex_mem_intf
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_master_driver.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_master_driver.sv
index e8117a5..34d9abb 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_master_driver.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_master_driver.sv
@@ -31,11 +31,11 @@
endtask : run_phase
virtual protected task get_and_drive();
- @(negedge vif.reset);
+ @(negedge vif.host_driver_cb.reset);
forever begin
- @(posedge vif.clock);
+ vif.wait_clks(1);
seq_item_port.get_next_item(req);
- repeat(req.req_delay) @(posedge vif.clock);
+ vif.wait_clks(req.req_delay);
$cast(rsp, req.clone());
rsp.set_id_info(req);
drive_transfer(rsp);
@@ -45,31 +45,31 @@
virtual protected task reset_signals();
forever begin
- @(posedge vif.reset);
- vif.request <= 'h0;
- vif.addr <= 'hz;
- vif.wdata <= 'hz;
- vif.be <= 'bz;
- vif.we <= 'bz;
+ @(posedge vif.host_driver_cb.reset);
+ vif.host_driver_cb.request <= 'h0;
+ vif.host_driver_cb.addr <= 'hz;
+ vif.host_driver_cb.wdata <= 'hz;
+ vif.host_driver_cb.be <= 'bz;
+ vif.host_driver_cb.we <= 'bz;
end
endtask : reset_signals
virtual protected task drive_transfer (ibex_mem_intf_seq_item trans);
if (trans.req_delay > 0) begin
- repeat(trans.req_delay) @(posedge vif.clock);
+ vif.wait_clks(trans.req_delay);
end
- vif.request <= 1'b1;
- vif.addr <= trans.addr;
- vif.be <= trans.be;
- vif.we <= trans.read_write;
- vif.wdata <= trans.data;
- wait(vif.grant === 1'b1);
- @(posedge vif.clock);
- vif.request <= 'h0;
- vif.addr <= 'hz;
- vif.wdata <= 'hz;
- vif.be <= 'bz;
- vif.we <= 'bz;
+ vif.host_driver_cb.request <= 1'b1;
+ vif.host_driver_cb.addr <= trans.addr;
+ vif.host_driver_cb.be <= trans.be;
+ vif.host_driver_cb.we <= trans.read_write;
+ vif.host_driver_cb.wdata <= trans.data;
+ wait (vif.host_driver_cb.grant === 1'b1);
+ vif.wait_clks(1);
+ vif.host_driver_cb.request <= 'h0;
+ vif.host_driver_cb.addr <= 'hz;
+ vif.host_driver_cb.wdata <= 'hz;
+ vif.host_driver_cb.be <= 'bz;
+ vif.host_driver_cb.we <= 'bz;
rdata_queue.put(trans);
endtask : drive_transfer
@@ -77,10 +77,10 @@
ibex_mem_intf_seq_item tr;
forever begin
rdata_queue.get(tr);
- @(posedge vif.clock);
- while(vif.rvalid !== 1'b1) @(posedge vif.clock);
+ vif.wait_clks(1);
+ while(vif.rvalid !== 1'b1) vif.wait_clks(1);
if(tr.read_write == READ)
- tr.data = vif.rdata;
+ tr.data = vif.host_driver_cb.rdata;
seq_item_port.put_response(tr);
end
endtask : collect_response
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_monitor.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_monitor.sv
index 8383e07..03d70dd 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_monitor.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_monitor.sv
@@ -28,12 +28,12 @@
endfunction: build_phase
virtual task run_phase(uvm_phase phase);
- wait(vif.reset === 1'b0);
+ wait (vif.monitor_cb.reset === 1'b0);
forever begin
fork : check_mem_intf
collect_address_phase();
collect_data_phase();
- wait(vif.reset === 1'b1);
+ wait (vif.monitor_cb.reset === 1'b1);
join_any
// Will only reach this point when mid-test reset is asserted
disable check_mem_intf;
@@ -45,21 +45,21 @@
ibex_mem_intf_seq_item mailbox_result;
// Clear the mailbox of any content
while (collect_data_queue.try_get(mailbox_result));
- wait(vif.reset === 1'b0);
+ wait (vif.monitor_cb.reset === 1'b0);
endtask
virtual protected task collect_address_phase();
ibex_mem_intf_seq_item trans_collected;
forever begin
trans_collected = ibex_mem_intf_seq_item::type_id::create("trans_collected");
- while(!(vif.request && vif.grant)) @(posedge vif.clock);
- trans_collected.addr = vif.addr;
- trans_collected.be = vif.be;
+ while(!(vif.monitor_cb.request && vif.monitor_cb.grant)) vif.wait_clks(1);
+ trans_collected.addr = vif.monitor_cb.addr;
+ trans_collected.be = vif.monitor_cb.be;
`uvm_info(get_full_name(), $sformatf("Detect request with address: %0x",
trans_collected.addr), UVM_HIGH)
- if(vif.we) begin
+ if(vif.monitor_cb.we) begin
trans_collected.read_write = WRITE;
- trans_collected.data = vif.wdata;
+ trans_collected.data = vif.monitor_cb.wdata;
end else begin
trans_collected.read_write = READ;
end
@@ -69,7 +69,7 @@
item_collected_port.write(trans_collected);
else
collect_data_queue.put(trans_collected);
- @(posedge vif.clock);
+ vif.wait_clks(1);
end
endtask : collect_address_phase
@@ -78,9 +78,9 @@
forever begin
collect_data_queue.get(trans_collected);
do
- @(posedge vif.clock);
- while(vif.rvalid === 0);
- trans_collected.data = vif.rdata;
+ vif.wait_clks(1);
+ while(vif.monitor_cb.rvalid === 0);
+ trans_collected.data = vif.monitor_cb.rdata;
item_collected_port.write(trans_collected);
end
endtask : collect_data_phase
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_slave_driver.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_slave_driver.sv
index 58520fe..3eb2f69 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_slave_driver.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/ibex_mem_intf_agent/ibex_mem_intf_slave_driver.sv
@@ -27,12 +27,12 @@
virtual task run_phase(uvm_phase phase);
reset_signals();
- wait(vif.reset === 1'b0);
+ wait (vif.device_driver_cb.reset === 1'b0);
forever begin
fork : drive_stimulus
send_grant();
get_and_drive();
- wait(vif.reset === 1'b1);
+ wait (vif.device_driver_cb.reset === 1'b1);
join_any
// Will only be reached after mid-test reset
disable drive_stimulus;
@@ -52,26 +52,26 @@
end
end while (req != null);
reset_signals();
- wait(vif.reset === 1'b0);
+ wait (vif.device_driver_cb.reset === 1'b0);
endtask
virtual protected task reset_signals();
- vif.rvalid <= 1'b0;
- vif.grant <= 1'b0;
- vif.rdata <= 'b0;
- vif.error <= 1'b0;
+ vif.device_driver_cb.rvalid <= 1'b0;
+ vif.device_driver_cb.grant <= 1'b0;
+ vif.device_driver_cb.rdata <= 'b0;
+ vif.device_driver_cb.error <= 1'b0;
endtask : reset_signals
virtual protected task get_and_drive();
- wait(vif.reset === 1'b0);
+ wait (vif.device_driver_cb.reset === 1'b0);
fork
begin
forever begin
ibex_mem_intf_seq_item req, req_c;
- @(posedge vif.clock);
+ vif.wait_clks(1);
seq_item_port.get_next_item(req);
$cast(req_c, req.clone());
- if(~vif.reset) begin
+ if(~vif.device_driver_cb.reset) begin
rdata_queue.put(req_c);
end
seq_item_port.item_done();
@@ -86,8 +86,8 @@
virtual protected task send_grant();
int gnt_delay;
forever begin
- while(vif.request !== 1'b1) begin
- @(negedge vif.clock);
+ while(vif.device_driver_cb.request !== 1'b1) begin
+ vif.wait_neg_clks(1);
end
if (!std::randomize(gnt_delay) with {
gnt_delay dist {
@@ -98,11 +98,11 @@
}) begin
`uvm_fatal(`gfn, $sformatf("Cannot randomize grant"))
end
- repeat(gnt_delay) @(negedge vif.clock);
- if(~vif.reset) begin
- vif.grant = 1'b1;
- @(negedge vif.clock);
- vif.grant = 1'b0;
+ vif.wait_neg_clks(gnt_delay);
+ if(~vif.device_driver_cb.reset) begin
+ vif.device_driver_cb.grant <= 1'b1;
+ vif.wait_neg_clks(1);
+ vif.device_driver_cb.grant <= 1'b0;
end
end
endtask : send_grant
@@ -110,17 +110,17 @@
virtual protected task send_read_data();
ibex_mem_intf_seq_item tr;
forever begin
- @(posedge vif.clock);
- vif.rvalid <= 1'b0;
- vif.rdata <= 'x;
- vif.error <= 1'b0;
+ vif.wait_clks(1);
+ vif.device_driver_cb.rvalid <= 1'b0;
+ vif.device_driver_cb.rdata <= 'x;
+ vif.device_driver_cb.error <= 1'b0;
rdata_queue.get(tr);
- if(vif.reset) continue;
- repeat(tr.rvalid_delay) @(posedge vif.clock);
- if(~vif.reset) begin
- vif.rvalid <= 1'b1;
- vif.error <= tr.error;
- vif.rdata <= tr.data;
+ if(vif.device_driver_cb.reset) continue;
+ vif.wait_clks(tr.rvalid_delay);
+ if(~vif.device_driver_cb.reset) begin
+ vif.device_driver_cb.rvalid <= 1'b1;
+ vif.device_driver_cb.error <= tr.error;
+ vif.device_driver_cb.rdata <= tr.data;
end
end
endtask : send_read_data
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_if.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_if.sv
index 138f50f..c57e615 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_if.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_if.sv
@@ -2,12 +2,34 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
-interface irq_if;
- logic clock;
+interface irq_if(input clk);
logic reset;
logic irq_software;
logic irq_timer;
logic irq_external;
logic [14:0] irq_fast;
logic irq_nm; // non-maskeable interrupt
+
+ clocking driver_cb @(posedge clk);
+ input reset;
+ output irq_software;
+ output irq_timer;
+ output irq_external;
+ output irq_fast;
+ output irq_nm;
+ endclocking
+
+ clocking monitor_cb @(posedge clk);
+ input reset;
+ input irq_software;
+ input irq_timer;
+ input irq_external;
+ input irq_fast;
+ input irq_nm;
+ endclocking
+
+ task automatic wait_clks(input int num);
+ repeat (num) @(posedge clk);
+ endtask
+
endinterface
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_master_driver.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_master_driver.sv
index defcde9..d695d95 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_master_driver.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_master_driver.sv
@@ -22,7 +22,7 @@
forever begin
fork : drive_irq
get_and_drive();
- wait(vif.reset === 1'b1);
+ wait (vif.driver_cb.reset === 1'b1);
join_any
// Will only reach here on mid-test reset
disable drive_irq;
@@ -43,7 +43,7 @@
endtask
virtual protected task get_and_drive();
- wait(vif.reset === 1'b0);
+ wait (vif.driver_cb.reset === 1'b0);
forever begin
seq_item_port.try_next_item(req);
if (req != null) begin
@@ -52,30 +52,30 @@
drive_seq_item(rsp);
seq_item_port.item_done(rsp);
end else begin
- @(posedge vif.clock);
+ vif.wait_clks(1);
end
end
endtask : get_and_drive
virtual protected task reset_signals();
- @(negedge vif.reset);
+ @(negedge vif.driver_cb.reset);
drive_reset_value();
endtask : reset_signals
virtual protected task drive_seq_item (irq_seq_item trans);
- vif.irq_software <= trans.irq_software;
- vif.irq_timer <= trans.irq_timer;
- vif.irq_external <= trans.irq_external;
- vif.irq_fast <= trans.irq_fast;
- vif.irq_nm <= trans.irq_nm;
+ vif.driver_cb.irq_software <= trans.irq_software;
+ vif.driver_cb.irq_timer <= trans.irq_timer;
+ vif.driver_cb.irq_external <= trans.irq_external;
+ vif.driver_cb.irq_fast <= trans.irq_fast;
+ vif.driver_cb.irq_nm <= trans.irq_nm;
endtask : drive_seq_item
task drive_reset_value();
- vif.irq_software <= '0;
- vif.irq_timer <= '0;
- vif.irq_external <= '0;
- vif.irq_fast <= '0;
- vif.irq_nm <= '0;
+ vif.driver_cb.irq_software <= '0;
+ vif.driver_cb.irq_timer <= '0;
+ vif.driver_cb.irq_external <= '0;
+ vif.driver_cb.irq_fast <= '0;
+ vif.driver_cb.irq_nm <= '0;
endtask : drive_reset_value
endclass : irq_master_driver
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_monitor.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_monitor.sv
index 639140d..050f552 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_monitor.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/common/irq_agent/irq_monitor.sv
@@ -23,10 +23,10 @@
virtual task run_phase(uvm_phase phase);
forever begin
- wait(vif.reset === 1'b0);
+ wait (vif.monitor_cb.reset === 1'b0);
fork : monitor_irq
collect_irq();
- wait(vif.reset === 1'b1);
+ wait (vif.monitor_cb.reset === 1'b1);
join_any
// Will only reach here on mid-test reset
disable monitor_irq;
@@ -46,19 +46,26 @@
bit[DATA_WIDTH-1:0] stored_irq_val = '0;
bit[DATA_WIDTH-1:0] current_irq = '0;
forever begin
- current_irq = {vif.irq_nm, vif.irq_fast, 4'b0, vif.irq_external, 3'b0,
- vif.irq_timer, 3'b0, vif.irq_software, 3'b0};
+ current_irq = {vif.monitor_cb.irq_nm,
+ vif.monitor_cb.irq_fast,
+ 4'b0,
+ vif.monitor_cb.irq_external,
+ 3'b0,
+ vif.monitor_cb.irq_timer,
+ 3'b0,
+ vif.monitor_cb.irq_software,
+ 3'b0};
if (current_irq !== stored_irq_val) begin
stored_irq_val = current_irq;
irq = irq_seq_item::type_id::create("irq");
- irq.irq_software = vif.irq_software;
- irq.irq_timer = vif.irq_timer;
- irq.irq_external = vif.irq_external;
- irq.irq_fast = vif.irq_fast;
- irq.irq_nm = vif.irq_nm;
+ irq.irq_software = vif.monitor_cb.irq_software;
+ irq.irq_timer = vif.monitor_cb.irq_timer;
+ irq.irq_external = vif.monitor_cb.irq_external;
+ irq.irq_fast = vif.monitor_cb.irq_fast;
+ irq.irq_nm = vif.monitor_cb.irq_nm;
irq_port.write(irq);
end
- @(posedge vif.clock);
+ vif.wait_clks(1);
end
endtask : collect_irq
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_csr_if.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_csr_if.sv
index 16f3fbc..399318f 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_csr_if.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_csr_if.sv
@@ -9,4 +9,13 @@
logic [31:0] csr_wdata;
logic [31:0] csr_rdata;
ibex_pkg::csr_op_e csr_op;
+
+ clocking csr_cb @(posedge clk);
+ input csr_access;
+ input csr_addr;
+ input csr_wdata;
+ input csr_rdata;
+ input csr_op;
+ endclocking
+
endinterface
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
index f350377..5f8b8cb 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/env/core_ibex_dut_probe_if.sv
@@ -16,6 +16,20 @@
logic debug_req;
ibex_pkg::priv_lvl_e priv_mode;
+ clocking dut_cb @(posedge clk);
+ output fetch_enable;
+ output debug_req;
+ input reset;
+ input illegal_instr;
+ input ecall;
+ input wfi;
+ input ebreak;
+ input dret;
+ input mret;
+ input core_sleep;
+ input priv_mode;
+ endclocking
+
initial begin
debug_req = 1'b0;
end
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/riscv_dv_extension/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/riscv_dv_extension/riscv_core_setting.sv
index f6938f0..937faf9 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/riscv_dv_extension/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/riscv_dv_extension/riscv_core_setting.sv
@@ -20,11 +20,19 @@
// XLEN
parameter int XLEN = 32;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 0;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 0;
+
// Vector extension parameters - not used in Ibex
parameter int VECTOR_EXTENSION_ENABLE = 0;
parameter int VLEN = 512;
parameter int ELEN = 64;
parameter int SLEN = 64;
+parameter int VELEN = 4;
+parameter int SELEN = 8;
+parameter int MAX_LMUL = 8;
// Number of harts
parameter int NUM_HARTS = 1;
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/sim_makefrag_gen.py b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/sim_makefrag_gen.py
index ea9003d..8187580 100755
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/sim_makefrag_gen.py
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/sim_makefrag_gen.py
@@ -65,6 +65,21 @@
'SIM_OPTS += {1}').format(riviera_compile_opts, riviera_sim_opts)
+def gen_questa_makefrag():
+ questa_compile_opts = run_ibex_config('questa_compile_opts', [
+ '--ins_hier_path', 'core_ibex_tb_top',
+ '--string_define_prefix', 'IBEX_CFG_'
+ ])
+
+ questa_sim_opts = run_ibex_config('questa_sim_opts', [
+ '--ins_hier_path', 'core_ibex_tb_top',
+ '--string_define_prefix', 'IBEX_CFG_'
+ ])
+
+ return ('COMPILE_OPTS += {0}'
+ 'SIM_OPTS += {1}').format(questa_compile_opts, questa_sim_opts)
+
+
def gen_xlm_makefrag():
xlm_compile_opts = run_ibex_config('xlm_opts', [
'--ins_hier_path', 'core_ibex_tb_top',
@@ -79,7 +94,12 @@
'Generates a makefile fragment for use with the Ibex DV makefile that '
'sets up sim specific variables'))
- sim_fns = {'vcs': gen_vcs_makefrag, 'riviera': gen_riviera_makefrag, 'xlm': gen_xlm_makefrag}
+ sim_fns = {
+ 'vcs': gen_vcs_makefrag,
+ 'riviera': gen_riviera_makefrag,
+ 'xlm': gen_xlm_makefrag,
+ 'questa': gen_questa_makefrag
+ }
argparser.add_argument('sim',
help='Name of the simulator',
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv
index 578fbe1..87c7a88 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tb/core_ibex_tb_top.sv
@@ -12,9 +12,9 @@
logic fetch_enable;
clk_if ibex_clk_if(.clk(clk), .rst_n(rst_n));
- irq_if irq_vif();
- ibex_mem_intf data_mem_vif();
- ibex_mem_intf instr_mem_vif();
+ irq_if irq_vif(.clk(clk));
+ ibex_mem_intf data_mem_vif(.clk(clk));
+ ibex_mem_intf instr_mem_vif(.clk(clk));
// DUT probe interface
@@ -89,10 +89,8 @@
);
// Data load/store vif connection
- assign data_mem_vif.clock = clk;
assign data_mem_vif.reset = ~rst_n;
// Instruction fetch vif connnection
- assign instr_mem_vif.clock = clk;
assign instr_mem_vif.reset = ~rst_n;
assign instr_mem_vif.we = 0;
assign instr_mem_vif.be = 0;
@@ -118,15 +116,14 @@
assign rvfi_if.mem_rdata = dut.rvfi_mem_rdata;
assign rvfi_if.mem_wdata = dut.rvfi_mem_wdata;
// Irq interface connections
- assign irq_vif.clock = clk;
assign irq_vif.reset = ~rst_n;
// Dut_if interface connections
- assign dut_if.ecall = dut.u_ibex_core.id_stage_i.ecall_insn_dec;
- assign dut_if.wfi = dut.u_ibex_core.id_stage_i.wfi_insn_dec;
- assign dut_if.ebreak = dut.u_ibex_core.id_stage_i.ebrk_insn;
- assign dut_if.illegal_instr = dut.u_ibex_core.id_stage_i.illegal_insn_dec;
- assign dut_if.dret = dut.u_ibex_core.id_stage_i.dret_insn_dec;
- assign dut_if.mret = dut.u_ibex_core.id_stage_i.mret_insn_dec;
+ assign dut_if.ecall = dut.u_ibex_core.id_stage_i.controller_i.ecall_insn;
+ assign dut_if.wfi = dut.u_ibex_core.id_stage_i.controller_i.wfi_insn;
+ assign dut_if.ebreak = dut.u_ibex_core.id_stage_i.controller_i.ebrk_insn;
+ assign dut_if.illegal_instr = dut.u_ibex_core.id_stage_i.controller_i.illegal_insn_d;
+ assign dut_if.dret = dut.u_ibex_core.id_stage_i.controller_i.dret_insn;
+ assign dut_if.mret = dut.u_ibex_core.id_stage_i.controller_i.mret_insn;
assign dut_if.reset = ~rst_n;
assign dut_if.priv_mode = dut.u_ibex_core.priv_mode_id;
// CSR interface connections
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_base_test.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_base_test.sv
index 9de3815..94fa672 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_base_test.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_base_test.sv
@@ -68,10 +68,10 @@
enable_irq_seq = cfg.enable_irq_single_seq || cfg.enable_irq_multiple_seq;
phase.raise_objection(this);
run = phase;
- dut_vif.fetch_enable = 1'b0;
+ dut_vif.dut_cb.fetch_enable <= 1'b0;
clk_vif.wait_clks(100);
load_binary_to_mem();
- dut_vif.fetch_enable = 1'b1;
+ dut_vif.dut_cb.fetch_enable <= 1'b1;
send_stimulus();
wait_for_test_done();
phase.drop_objection(this);
@@ -116,11 +116,11 @@
virtual task wait_for_test_done();
fork
begin
- wait (dut_vif.ecall === 1'b1);
+ wait (dut_vif.dut_cb.ecall === 1'b1);
vseq.stop();
`uvm_info(`gfn, "ECALL instruction is detected, test done", UVM_LOW)
// De-assert fetch enable to finish the test
- dut_vif.fetch_enable = 1'b0;
+ dut_vif.dut_cb.fetch_enable <= 1'b0;
fork
check_perf_stats();
// Wait some time for the remaining instruction to finish
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv
index c016129..1ec9da3 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_seq_lib.sv
@@ -131,15 +131,15 @@
if (!uvm_config_db#(virtual core_ibex_dut_probe_if)::get(null, "", "dut_if", dut_vif)) begin
`uvm_fatal(get_full_name(), "Cannot get dut_if")
end
- dut_vif.debug_req <= 1'b0;
+ dut_vif.dut_cb.debug_req <= 1'b0;
super.body();
endtask
virtual task send_req();
`uvm_info(get_full_name(), "Sending debug request", UVM_HIGH)
- dut_vif.debug_req <= 1'b1;
+ dut_vif.dut_cb.debug_req <= 1'b1;
clk_vif.wait_clks(50);
- dut_vif.debug_req <= 1'b0;
+ dut_vif.dut_cb.debug_req <= 1'b0;
endtask
endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv
index 01b000c..7d86982 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/tests/core_ibex_test_lib.sv
@@ -47,7 +47,7 @@
clk_vif.wait_clks($urandom_range(0, 50000));
fork
begin
- dut_vif.fetch_enable = 1'b0;
+ dut_vif.dut_cb.fetch_enable <= 1'b0;
clk_vif.reset();
end
begin
@@ -61,7 +61,7 @@
end
join
// Assert fetch_enable to have the core start executing from boot address
- dut_vif.fetch_enable = 1'b1;
+ dut_vif.dut_cb.fetch_enable <= 1'b1;
end
endtask
@@ -223,7 +223,7 @@
end
check_next_core_status(HANDLING_IRQ, "Core did not jump to vectored interrupt handler", 750);
check_priv_mode(PRIV_LVL_M);
- operating_mode = dut_vif.priv_mode;
+ operating_mode = dut_vif.dut_cb.priv_mode;
// check mstatus
wait_for_csr_write(CSR_MSTATUS, 500);
mstatus = signature_data;
@@ -329,16 +329,16 @@
begin
case (ret)
"dret": begin
- wait (dut_vif.dret === 1'b1);
+ wait (dut_vif.dut_cb.dret === 1'b1);
end
"mret": begin
- wait (dut_vif.mret === 1'b1);
+ wait (dut_vif.dut_cb.mret === 1'b1);
end
default: begin
`uvm_fatal(`gfn, $sformatf("Invalid xRET instruction %0s", ret))
end
endcase
- wait (dut_vif.priv_mode === select_mode());
+ wait (dut_vif.dut_cb.priv_mode === select_mode());
end
begin : ret_timeout
clk_vif.wait_clks(timeout);
@@ -352,7 +352,7 @@
endtask
virtual function void check_priv_mode(priv_lvl_e mode);
- `DV_CHECK_EQ_FATAL(dut_vif.priv_mode, mode,
+ `DV_CHECK_EQ_FATAL(dut_vif.dut_cb.priv_mode, mode,
"Incorrect privilege mode")
endfunction
@@ -397,7 +397,7 @@
check_stimulus();
end : stimulus
begin
- wait(dut_vif.ecall === 1'b1);
+ wait (dut_vif.dut_cb.ecall === 1'b1);
disable stimulus;
if (run.get_objection_count(this) > 1) begin
run.drop_objection(this);
@@ -475,8 +475,8 @@
virtual task check_stimulus();
forever begin
- wait (dut_vif.wfi === 1'b1);
- wait(dut_vif.core_sleep === 1'b1);
+ wait (dut_vif.dut_cb.wfi === 1'b1);
+ wait (dut_vif.dut_cb.core_sleep === 1'b1);
send_irq_stimulus();
end
endtask
@@ -492,13 +492,15 @@
virtual task check_stimulus();
vseq.irq_raise_single_seq_h.max_delay = 0;
// wait for a write to mstatus - should be in init code
- wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MSTATUS &&
- csr_vif.csr_op != CSR_OP_READ);
+ wait (csr_vif.csr_cb.csr_access === 1'b1 &&
+ csr_vif.csr_cb.csr_addr === CSR_MSTATUS &&
+ csr_vif.csr_cb.csr_op != CSR_OP_READ);
// send interrupt immediately after detection
send_irq_stimulus();
// wait for a write to mie - should be in init code
- wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MIE &&
- csr_vif.csr_op != CSR_OP_READ);
+ wait (csr_vif.csr_cb.csr_access === 1'b1 &&
+ csr_vif.csr_cb.csr_addr === CSR_MIE &&
+ csr_vif.csr_cb.csr_op != CSR_OP_READ);
// send interrupt immediately after detection
send_irq_stimulus();
endtask
@@ -562,7 +564,7 @@
send_debug_stimulus(operating_mode, "Core did not enter debug mode from interrupt handler");
end
begin
- wait(dut_vif.dret == 1'b1);
+ wait (dut_vif.dut_cb.dret == 1'b1);
send_irq_stimulus_end();
end
join
@@ -591,8 +593,9 @@
// Send nested interrupt after the checks of the first interrupt have finished
in_nested_trap = 1'b1;
// wait until we are setting mstatus.mie to 1'b1 to send the next set of interrupts
- wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MSTATUS &&
- csr_vif.csr_op != CSR_OP_READ);
+ wait (csr_vif.csr_cb.csr_access === 1'b1 &&
+ csr_vif.csr_cb.csr_addr === CSR_MSTATUS &&
+ csr_vif.csr_cb.csr_op != CSR_OP_READ);
send_irq_stimulus(1'b0);
vseq.irq_raise_seq_h.max_delay = initial_irq_delay;
in_nested_trap = 1'b0;
@@ -611,8 +614,8 @@
virtual task check_stimulus();
forever begin
- wait (dut_vif.wfi === 1'b1);
- wait (dut_vif.core_sleep === 1'b1);
+ wait (dut_vif.dut_cb.wfi === 1'b1);
+ wait (dut_vif.dut_cb.core_sleep === 1'b1);
clk_vif.wait_clks($urandom_range(100));
send_debug_stimulus(init_operating_mode, "Core did not jump into debug mode from WFI state");
end
@@ -629,12 +632,14 @@
virtual task check_stimulus();
vseq.debug_seq_single_h.max_delay = 0;
// wait for a dummy write to mstatus in init code
- wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MSTATUS &&
- csr_vif.csr_op != CSR_OP_READ);
+ wait (csr_vif.csr_cb.csr_access === 1'b1 &&
+ csr_vif.csr_cb.csr_addr === CSR_MSTATUS &&
+ csr_vif.csr_cb.csr_op != CSR_OP_READ);
send_debug_stimulus(init_operating_mode, "Core did not trap to debug mode upon debug stimulus");
// wait for a dummy write to mie in the init code
- wait(csr_vif.csr_access === 1'b1 && csr_vif.csr_addr === CSR_MIE &&
- csr_vif.csr_op != CSR_OP_READ);
+ wait (csr_vif.csr_cb.csr_access === 1'b1 &&
+ csr_vif.csr_cb.csr_addr === CSR_MIE &&
+ csr_vif.csr_cb.csr_op != CSR_OP_READ);
send_debug_stimulus(init_operating_mode, "Core did not trap to debug mode upon debug stimulus");
endtask
@@ -648,7 +653,7 @@
virtual task check_stimulus();
forever begin
- wait (dut_vif.dret === 1'b1);
+ wait (dut_vif.dut_cb.dret === 1'b1);
check_illegal_insn("Core did not treat dret like illegal instruction");
end
endtask
@@ -678,7 +683,7 @@
// capture the first write of dpc
wait_for_csr_write(CSR_DPC, 500);
dpc = signature_data;
- wait (dut_vif.ebreak === 1'b1);
+ wait (dut_vif.dut_cb.ebreak === 1'b1);
// compare the second writes of dcsr and dpc against the captured values
wait_for_csr_write(CSR_DCSR, 1000);
`DV_CHECK_EQ_FATAL(dcsr, signature_data,
@@ -713,7 +718,7 @@
check_dcsr_cause(DBG_CAUSE_HALTREQ);
wait_ret("dret", 5000);
forever begin
- wait (dut_vif.ebreak === 1'b1);
+ wait (dut_vif.dut_cb.ebreak === 1'b1);
check_next_core_status(IN_DEBUG_MODE,
"Core did not enter debug mode after execution of ebreak", 2000);
check_priv_mode(PRIV_LVL_M);
@@ -840,7 +845,7 @@
exc_type = EXC_CAUSE_STORE_ACCESS_FAULT;
end
check_mcause(1'b0, exc_type);
- wait (dut_vif.mret === 1'b1);
+ wait (dut_vif.dut_cb.mret === 1'b1);
`uvm_info(`gfn, "exiting mem fault checker", UVM_LOW)
endtask
@@ -876,7 +881,7 @@
"Core did not register correct memory fault type", 500);
exc_type = EXC_CAUSE_INSTR_ACCESS_FAULT;
check_mcause(1'b0, exc_type);
- wait (dut_vif.mret === 1'b1);
+ wait (dut_vif.dut_cb.mret === 1'b1);
`uvm_info(`gfn, "exiting mem fault checker", UVM_LOW)
endtask
@@ -891,7 +896,7 @@
virtual task check_stimulus();
bit [ibex_mem_intf_agent_pkg::DATA_WIDTH-1:0] mcause;
forever begin
- wait (dut_vif.wfi === 1'b1);
+ wait (dut_vif.dut_cb.wfi === 1'b1);
check_illegal_insn("Core did not treat U-mode WFI as illegal");
end
endtask
@@ -907,9 +912,9 @@
virtual task check_stimulus();
forever begin
// Wait for a CSR access
- wait (csr_vif.csr_access == 1'b1);
+ wait (csr_vif.csr_cb.csr_access == 1'b1);
check_illegal_insn($sformatf("Core did not treat access to CSR 0x%0x from %0s as illegal",
- csr_vif.csr_addr, init_operating_mode));
+ csr_vif.csr_cb.csr_addr, init_operating_mode));
end
endtask
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/yaml/rtl_simulation.yaml b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/yaml/rtl_simulation.yaml
index 81d2adf..cfceb73 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/yaml/rtl_simulation.yaml
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/core_ibex/yaml/rtl_simulation.yaml
@@ -52,6 +52,25 @@
wave_opts: >
-ucli -do <cwd>/vcs.tcl
+- tool: questa
+ compile:
+ cmd:
+ - "vmap mtiUvm $QUESTA_HOME/questasim/uvm-1.2"
+ - "vlog -64
+ -access=rwc
+ -f ibex_dv.f
+ -sv
+ -mfcu -cuname design_cuname
+ +define+UVM_REGEX_NO_DPI
+ +define+UVM
+ -writetoplevels <out>/top.list
+ -l <out>/compile.log <cmp_opts>"
+ sim:
+ cmd: >
+ vsim -64 -c <cov_opts> -do "run -a; quit -f" +designfile -f <out>/top.list <sim_opts> -sv_seed <seed> +access +r+w +UVM_TESTNAME=<rtl_test> +bin=<binary> +ibex_tracer_file_base="<sim_dir>/trace_core" -l <sim_dir>/sim.log
+ cov_opts: >
+ -do "coverage save -onexit <out>/cov.ucdb;"
+
- tool: dsim
env_var: DSIM,DSIM_LIB_PATH
compile:
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/data/ibex_icache_testplan.hjson b/hw/vendor/lowrisc_ibex/dv/uvm/icache/data/ibex_icache_testplan.hjson
index 68b9258..6ccd1d8 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/data/ibex_icache_testplan.hjson
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/data/ibex_icache_testplan.hjson
@@ -118,17 +118,17 @@
bit error. Check that the invalid cached data is correctly
ignored.'''
milestone: V2
- tests: []
+ tests: ["ibex_icache_ecc"]
}
{
name: stress_all
- desc: '''Run a pair of sequences back-to-back
+ desc: '''Run sequences back-to-back
Tests are selected from the sequences above. With 50% probability,
reset between the sequences.'''
milestone: V2
- tests: []
+ tests: ["ibex_icache_stress_all"]
}
{
@@ -138,7 +138,7 @@
Tests are selected from the sequences above. Add occasional
resets (in the middle of sequences)'''
milestone: V2
- tests: []
+ tests: ["ibex_icache_stress_all_with_reset"]
}
]
}
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/doc/ibex_icache_dv_plan.md b/hw/vendor/lowrisc_ibex/dv/uvm/icache/doc/ibex_icache_dv_plan.md
index e6c4877..c699b27 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/doc/ibex_icache_dv_plan.md
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/doc/ibex_icache_dv_plan.md
@@ -26,18 +26,22 @@
This means that the testbench cannot compare the DUT with a reference model, nor can it model the exact requests that the DUT will make of instruction memory: the whole point of a cache is that it might avoid an instruction fetch.
The cache has two main interfaces, which face the core and instruction bus respectively.
-We model this with two agents: the *core agent* and the *memory agent*.
+We model this with two main agents: the *core agent* and the *memory agent*.
The core agent will emulate a core making instruction fetch requests from the cache and the memory agent will emulate the instruction bus.
-In fact, there's one more logical interface: the `busy_o` signal from the cache.
+In fact, there's one more logical interface at the top-level: the `busy_o` signal from the cache.
This signal is passed up to top-level in the design and warns the chip not to clock-gate or reset the core (because there are bus transactions in flight, or a memory invalidation in progress).
Rather than have an extra agent just for this single-bit passive signal, we pass the signal to the monitor in the core agent, which reports changes to the scoreboard.
+Finally, we bind an interface in for each RAM in the cache.
+These interfaces are controlled by instances of the *ECC agent*, which is in charge of injecting occasional one- and two-bit errors which should be spotted by the cache's ECC checks.
+

-Both agents report events to the scoreboard.
+Both main agents report events to the scoreboard.
The core agent reports whether the cache is busy, every branch sent to the cache, invalidation requests, enabling/disabling the cache and every instruction fetched (address and contents).
The memory agent reports every change of seed (see the [Memory Agent](#memory-agent) section below).
+The ECC agents don't currently report to the scoreboard, since they aren't supposed to have any architectural effect.
### Agents
@@ -73,6 +77,11 @@
The memory agent is an active slave, responding to instruction fetches from the cache with either a PMP error (on the same cycle as the request) or instruction data (with an in-order request pipeline).
+#### ECC Agent
+
+Each ECC agent emulates possible data corruption in the cache's underlying memories.
+The sole sequence causes occasional 1- or 2-bit errors, injected by XORing valid data from the underlying memory with a mask.
+
### Top level testbench
The top level testbench is located at [`dv/uvm/icache/dv/tb/tb.sv`](https://github.com/lowRISC/ibex/blob/master/dv/uvm/icache/dv/tb/tb.sv). It instantiates the `ibex_icache` DUT module whose source is at [`rtl/ibex_icache.sv`](https://github.com/lowRISC/ibex/blob/master/rtl/ibex_icache.sv).
@@ -80,6 +89,7 @@
* Clock and reset interface ([`vendor/lowrisc_ip/common_ifs`](https://github.com/lowRISC/ibex/tree/master/vendor/lowrisc_ip/common_ifs))
* Core interface ([`dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_if.sv`](https://github.com/lowRISC/ibex/blob/master/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_if.sv))
* Memory interface ([`dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_if.sv`](https://github.com/lowRISC/ibex/blob/master/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_if.sv))
+* ECC interfaces ([`dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_if.sv`](https://github.com/lowRISC/ibex/blob/master/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_if.sv))
### Common DV utility components
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/doc/tb.svg b/hw/vendor/lowrisc_ibex/dv/uvm/icache/doc/tb.svg
index ceb6282..37a962e 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/doc/tb.svg
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/doc/tb.svg
@@ -7,15 +7,15 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- version="1.1"
- viewBox="0 0 1051 671"
- stroke-miterlimit="10"
- id="svg1659"
- sodipodi:docname="tb.svg"
- inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+ style="fill:none;stroke:none;stroke-linecap:square;stroke-miterlimit:10"
+ height="721"
width="1051"
- height="671"
- style="fill:none;stroke:none;stroke-linecap:square;stroke-miterlimit:10">
+ inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
+ sodipodi:docname="tb.svg"
+ id="svg1659"
+ stroke-miterlimit="10"
+ viewBox="0 0 1051 721"
+ version="1.1">
<metadata
id="metadata1665">
<rdf:RDF>
@@ -31,497 +31,338 @@
<defs
id="defs1663">
<marker
- inkscape:stockid="Arrow1Lend"
- orient="auto"
- refY="0"
- refX="0"
- id="Arrow1Lend"
+ inkscape:isstock="true"
style="overflow:visible"
- inkscape:isstock="true">
+ id="Arrow1Lend"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow1Lend">
<path
- id="path7702"
- d="M 0,0 5,-5 -12.5,0 5,5 Z"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+ inkscape:connector-curvature="0"
transform="matrix(-0.8,0,0,-0.8,-10,0)"
- inkscape:connector-curvature="0" />
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ id="path7702" />
</marker>
</defs>
<sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1920"
- inkscape:window-height="1043"
- id="namedview1661"
- showgrid="true"
- inkscape:zoom="1.0440636"
- inkscape:cx="531.97562"
- inkscape:cy="326.55768"
- inkscape:window-x="1920"
- inkscape:window-y="0"
- inkscape:window-maximized="1"
- inkscape:current-layer="g2507"
- fit-margin-top="0"
- fit-margin-left="0"
+ inkscape:guide-bbox="true"
+ showguides="true"
+ inkscape:document-rotation="0"
+ fit-margin-bottom="0"
fit-margin-right="0"
- fit-margin-bottom="0">
+ fit-margin-left="0"
+ fit-margin-top="0"
+ inkscape:current-layer="svg1659"
+ inkscape:window-maximized="1"
+ inkscape:window-y="0"
+ inkscape:window-x="0"
+ inkscape:cy="334.71118"
+ inkscape:cx="375.46262"
+ inkscape:zoom="0.73826445"
+ showgrid="true"
+ id="namedview1661"
+ inkscape:window-height="1043"
+ inkscape:window-width="1920"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ guidetolerance="10"
+ gridtolerance="10"
+ objecttolerance="10"
+ borderopacity="1"
+ bordercolor="#666666"
+ pagecolor="#ffffff">
<inkscape:grid
- type="xygrid"
+ originy="-109.5"
+ originx="-49.500001"
id="grid1791"
- originx="-49.499996"
- originy="-109.5" />
+ type="xygrid" />
</sodipodi:namedview>
<clipPath
id="p.0">
<path
- d="M 0,0 H 1086 V 817 H 0 Z"
- id="path1438"
+ style="clip-rule:nonzero"
inkscape:connector-curvature="0"
- style="clip-rule:nonzero" />
+ id="path1438"
+ d="M 0,0 H 1086 V 817 H 0 Z" />
</clipPath>
<path
- style="fill:#000000;fill-opacity:0;fill-rule:evenodd"
- inkscape:connector-curvature="0"
+ d="M -49.500001,-36.500001 H 1036.5 V 780.5 H -49.500001 Z"
id="path1441"
- d="M -49.499996,-36.5 H 1036.5 v 817 H -49.499996 Z" />
- <path
- style="fill:#000000;fill-opacity:0;fill-rule:evenodd"
inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:0;fill-rule:evenodd" />
+ <path
+ d="m 399.76248,507.2441 c 0,12.49915 -57.79852,51.22955 -103.7601,24.99829 -45.96161,-26.23126 -80.0863,-117.42416 -103.7601,-208.61664 -23.6738,-91.1925 -36.89667,-182.3845 -61.95644,-208.6167 -25.05978,-26.232181 -61.956441,12.49548 -61.956441,24.99097"
id="path1497"
- d="m 399.76248,507.2441 c 0,12.49915 -57.79852,51.22955 -103.7601,24.99829 -45.96161,-26.23126 -80.0863,-117.42416 -103.7601,-208.61664 -23.6738,-91.1925 -36.89667,-182.3845 -61.95644,-208.6167 -25.05978,-26.23218 -61.956436,12.49548 -61.956436,24.99097" />
- <path
- style="fill:#000000;fill-opacity:0;fill-rule:evenodd"
inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:0;fill-rule:evenodd" />
+ <path
+ d="m 241.68896,288.44882 c 12.51828,0 12.82883,64.17889 25.03653,121.89743 12.20767,57.71851 36.31247,108.97662 66.52112,121.8974 30.20862,12.92078 66.52112,-12.49585 66.52112,-24.9917"
id="path1539"
- d="m 241.68896,288.44882 c 12.51828,0 12.82883,64.17889 25.03653,121.89743 12.20767,57.71851 36.31247,108.97662 66.52112,121.8974 30.20862,12.92078 66.52112,-12.49585 66.52112,-24.9917" />
- <path
- style="fill:#000000;fill-opacity:0;fill-rule:evenodd"
inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:0;fill-rule:evenodd" />
+ <path
+ d="m 241.68896,220.05774 c 12.51828,0 12.82883,82.41611 25.03653,156.09299 12.20767,73.67688 36.31247,138.61453 66.52112,156.09299 30.20862,17.47839 66.52112,-12.50244 66.52112,-25.00488"
id="path1543"
- d="m 241.68896,220.05774 c 12.51828,0 12.82883,82.41611 25.03653,156.09299 12.20767,73.67688 36.31247,138.61453 66.52112,156.09299 30.20862,17.47839 66.52112,-12.50244 66.52112,-25.00488" />
- <path
- style="fill:#000000;fill-opacity:0;fill-rule:evenodd"
inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:0;fill-rule:evenodd" />
+ <path
+ d="M 27.429129,672.96063 C 14.929114,672.96063 0.66137928,576.83465 2.4290953,480.70868 4.1968113,384.58267 21.999984,288.4567 41.570868,288.4567"
id="path1579"
- d="M 27.429134,672.96063 C 14.929119,672.96063 0.66138378,576.83465 2.4290998,480.70868 4.1968158,384.58267 21.999989,288.4567 41.570873,288.4567" />
- <path
- style="fill:#000000;fill-opacity:0;fill-rule:evenodd"
inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:0;fill-rule:evenodd" />
+ <path
+ d="m 567.7257,12.017604 h 454.0787 V 256.0491 H 567.7257 Z"
id="path1593"
- d="m 567.7257,12.017605 h 454.0787 V 256.0491 H 567.7257 Z" />
- <path
- style="fill:#000000;fill-opacity:0;fill-rule:evenodd"
inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:0;fill-rule:evenodd" />
+ <path
+ d="M 565.26904,260.10367 H 1024.2611 V 497.39502 H 565.26904 Z"
id="path1615"
- d="M 565.26904,260.10367 H 1024.2611 V 497.39502 H 565.26904 Z" />
- <path
- style="fill:#000000;fill-opacity:0;fill-rule:evenodd"
inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:0;fill-rule:evenodd" />
+ <path
+ d="m 399.76248,507.2441 c 0,12.50079 -36.3114,47.04083 -66.51877,25.00159 C 303.03634,510.20644 278.93298,431.58785 266.72497,341.94964 254.51696,252.31142 254.20434,151.65357 241.68371,151.65357"
id="path1653"
- d="m 399.76248,507.2441 c 0,12.50079 -36.3114,47.04083 -66.51877,25.00159 C 303.03634,510.20644 278.93298,431.58785 266.72497,341.94964 254.51696,252.31142 254.20434,151.65357 241.68371,151.65357" />
+ inkscape:connector-curvature="0"
+ style="fill:#000000;fill-opacity:0;fill-rule:evenodd" />
<rect
- ry="90.000008"
- rx="90"
- y="10.5"
- x="10.500019"
- height="640"
- width="530"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fff8e3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect2206"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fff8e3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666794px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f18080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="274.93945"
- y="42.595207"
- id="text1777"><tspan
- sodipodi:role="line"
- id="tspan1775"
- x="274.93945"
- y="42.595207"
- style="fill:#000000;fill-opacity:1">ibex_icache_base_test</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="575.61847"
- y="295.76044"
- id="text8237"><tspan
- sodipodi:role="line"
- x="575.61847"
- y="295.76044"
- id="tspan8151"><tspan
- x="575.61847"
- y="295.76044"
- id="tspan8147">Square boxes: SV modules / interfaces (static)</tspan><tspan
- dx="0"
- x="904.83722"
- y="295.76044"
- id="tspan8149" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="315.76044"
- id="tspan8157"><tspan
- x="575.61847"
- y="315.76044"
- id="tspan8153">Rounded boxes: SV classes (UVM; dynamically created)</tspan><tspan
- dx="0"
- x="976.93097"
- y="315.76044"
- id="tspan8155" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="335.76044"
- id="tspan8163"><tspan
- x="575.61847"
- y="335.76044"
- id="tspan8159">Square box with cut corner: Code block (a UVM phase)</tspan><tspan
- dx="0"
- x="967.14966"
- y="335.76044"
- id="tspan8161" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="355.76044"
- id="tspan8167"><tspan
- x="575.61847"
- y="355.76044"
- id="tspan8165" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="375.76044"
- id="tspan8171"><tspan
- x="575.61847"
- y="375.76044"
- id="tspan8169">Nesting shows fields in classes, so there is an object of type </tspan></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="395.76041"
- id="tspan8175"><tspan
- x="575.61847"
- y="395.76041"
- id="tspan8173">ibex_icache_env inside the object of type </tspan></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="415.76041"
- id="tspan8181"><tspan
- x="575.61847"
- y="415.76041"
- id="tspan8177">ibex_icache_base_test.</tspan><tspan
- dx="0"
- x="742.93097"
- y="415.76041"
- id="tspan8179" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="435.76041"
- id="tspan8185"><tspan
- x="575.61847"
- y="435.76041"
- id="tspan8183" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="455.76041"
- id="tspan8189"><tspan
- x="575.61847"
- y="455.76041"
- id="tspan8187">The color of the box for a class shows the base class. For </tspan></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="475.76041"
- id="tspan8195"><tspan
- x="575.61847"
- y="475.76041"
- id="tspan8191">example, interfaces are pink; agents are green.</tspan><tspan
- dx="0"
- x="910.21222"
- y="475.76041"
- id="tspan8193" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="495.76041"
- id="tspan8199"><tspan
- x="575.61847"
- y="495.76041"
- id="tspan8197" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="515.76038"
- id="tspan8203"><tspan
- x="575.61847"
- y="515.76038"
- id="tspan8201">Many classes have handles (always called cfg) to the test's </tspan></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="535.76038"
- id="tspan8207"><tspan
- x="575.61847"
- y="535.76038"
- id="tspan8205">ibex_icache_env_cfg object. To denote this, those classes are </tspan></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="555.76038"
- id="tspan8213"><tspan
- x="575.61847"
- y="555.76038"
- id="tspan8209">connected by a dotted line to the ibex_icache_env_cfg class.</tspan><tspan
- dx="0"
- x="1006.2747"
- y="555.76038"
- id="tspan8211" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="575.76038"
- id="tspan8217"><tspan
- x="575.61847"
- y="575.76038"
- id="tspan8215" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="595.76038"
- id="tspan8221"><tspan
- x="575.61847"
- y="595.76038"
- id="tspan8219">The virtual sequence object created in the run phase has a </tspan></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="615.76038"
- id="tspan8225"><tspan
- x="575.61847"
- y="615.76038"
- id="tspan8223">p_sequencer handle to the ibex_icache_virtual_sequencer </tspan></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="635.76038"
- id="tspan8231"><tspan
- x="575.61847"
- y="635.76038"
- id="tspan8227">inside the environment (not shown).</tspan><tspan
- dx="0"
- x="829.24347"
- y="635.76038"
- id="tspan8229" /></tspan><tspan
- sodipodi:role="line"
- x="575.61847"
- y="635.76038"
- id="tspan8235"><tspan
- x="575.61847"
- y="655.76038"
- id="tspan8233" /></tspan></text>
- <g
- id="g2617"
- transform="translate(-49.499996,-36.5)">
- <rect
- ry="40"
- rx="40"
- y="107"
- x="70"
- height="310"
- width="239.99998"
- id="rect1908"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fff2cc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
- <text
- transform="scale(1.0069205,0.99312707)"
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:19.8625412px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f18080;fill-opacity:1;stroke:none;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="189.25031"
- y="140.77362"
- id="text1785"><tspan
- sodipodi:role="line"
- id="tspan1783"
- x="189.25031"
- y="140.77362"
- style="fill:#000000;fill-opacity:1;stroke-width:0.99999994px">ibex_icache_env</tspan></text>
- <g
- transform="translate(-5,-39.999999)"
- id="g1896">
- <rect
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffe599;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect1831"
- width="229.99998"
- height="36.322979"
- x="80"
- y="205.67702"
- ry="10"
- rx="9.999999" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="194.49219"
- y="228.39612"
- id="text1789"><tspan
- sodipodi:role="line"
- id="tspan1787"
- x="194.49219"
- y="228.39612">ibex_icache_env_cov</tspan></text>
- </g>
- <g
- transform="translate(-4.9999695,-36.322967)"
- id="g1901">
- <rect
- rx="9.999999"
- ry="10"
- y="247"
- x="79.999992"
- height="36.322979"
- width="229.99998"
- id="rect1852"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffe599;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
- <text
- id="text1856"
- y="269.71912"
- x="194.98438"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- y="269.71912"
- x="194.98438"
- id="tspan1854"
- sodipodi:role="line">ibex_icache_scoreboard</tspan></text>
- </g>
- <g
- transform="translate(-5,-31.322968)"
- id="g1906">
- <rect
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffe599;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect1876"
- width="229.99998"
- height="36.322979"
- x="80"
- y="287"
- ry="10"
- rx="9.999999" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="194.98438"
- y="309.71912"
- id="text1880"><tspan
- sodipodi:role="line"
- id="tspan1878"
- x="194.98438"
- y="309.71912">ibex_icache_virtual_sequencer</tspan></text>
- </g>
- <g
- transform="translate(0,-45)"
- id="g2036">
- <rect
- rx="9.999999"
- ry="10"
- y="355.67703"
- x="75"
- height="36.322979"
- width="229.99998"
- id="rect2008"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
- <text
- id="text2012"
- y="378.39615"
- x="189.98438"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- y="378.39615"
- x="189.98438"
- id="tspan2010"
- sodipodi:role="line">ibex_icache_core_agent</tspan></text>
- </g>
- <g
- id="g2044">
- <rect
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect2038"
- width="229.99998"
- height="36.322979"
- x="75"
- y="355.67703"
- ry="10"
- rx="9.999999" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="189.98438"
- y="378.39615"
- id="text2042"><tspan
- sodipodi:role="line"
- id="tspan2040"
- x="189.98438"
- y="378.39615">ibex_icache_mem_agent</tspan></text>
- </g>
- </g>
- <rect
- ry="40"
+ width="530"
+ height="700"
+ x="10.500014"
+ y="10.499999"
rx="40"
- y="70.5"
- x="290.5"
- height="310"
- width="239.99998"
- id="rect2074"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffe599;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.99999988;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ ry="40.000004" />
<text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666794px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f18080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="410.48175"
+ id="text1777"
+ y="42.595207"
+ x="274.93945"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f18080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#000000;fill-opacity:1"
+ y="42.595207"
+ x="274.93945"
+ id="tspan1775"
+ sodipodi:role="line">ibex_icache_base_test</tspan></text>
+ <text
+ id="text8237"
+ y="295.76044"
+ x="575.61847"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan8151"
+ y="295.76044"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8147"
+ y="295.76044"
+ x="575.61847">Square boxes: SV modules / interfaces (static)</tspan><tspan
+ id="tspan8149"
+ y="295.76044"
+ x="904.83722"
+ dx="0" /></tspan><tspan
+ id="tspan8157"
+ y="315.76044"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8153"
+ y="315.76044"
+ x="575.61847">Rounded boxes: SV classes (UVM; dynamically created)</tspan><tspan
+ id="tspan8155"
+ y="315.76044"
+ x="976.93097"
+ dx="0" /></tspan><tspan
+ id="tspan8163"
+ y="335.76044"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8159"
+ y="335.76044"
+ x="575.61847">Square box with cut corner: Code block (a UVM phase)</tspan><tspan
+ id="tspan8161"
+ y="335.76044"
+ x="967.14966"
+ dx="0" /></tspan><tspan
+ id="tspan8167"
+ y="355.76044"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8165"
+ y="355.76044"
+ x="575.61847" /></tspan><tspan
+ id="tspan8171"
+ y="375.76044"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8169"
+ y="375.76044"
+ x="575.61847">Nesting shows fields in classes, so there is an object of type </tspan></tspan><tspan
+ id="tspan8175"
+ y="395.76041"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8173"
+ y="395.76041"
+ x="575.61847">ibex_icache_env inside the object of type </tspan></tspan><tspan
+ id="tspan8181"
+ y="415.76041"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8177"
+ y="415.76041"
+ x="575.61847">ibex_icache_base_test.</tspan><tspan
+ id="tspan8179"
+ y="415.76041"
+ x="742.93097"
+ dx="0" /></tspan><tspan
+ id="tspan8185"
+ y="435.76041"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8183"
+ y="435.76041"
+ x="575.61847" /></tspan><tspan
+ id="tspan8189"
+ y="455.76041"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8187"
+ y="455.76041"
+ x="575.61847">The color of the box for a class shows the base class. For </tspan></tspan><tspan
+ id="tspan8195"
+ y="475.76041"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8191"
+ y="475.76041"
+ x="575.61847">example, interfaces are pink; agents are green.</tspan><tspan
+ id="tspan8193"
+ y="475.76041"
+ x="910.21222"
+ dx="0" /></tspan><tspan
+ id="tspan8199"
+ y="495.76041"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8197"
+ y="495.76041"
+ x="575.61847" /></tspan><tspan
+ id="tspan8203"
+ y="515.76038"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8201"
+ y="515.76038"
+ x="575.61847">Many classes have handles (always called cfg) to the test's </tspan></tspan><tspan
+ id="tspan8207"
+ y="535.76038"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8205"
+ y="535.76038"
+ x="575.61847">ibex_icache_env_cfg object. To denote this, those classes are </tspan></tspan><tspan
+ id="tspan8213"
+ y="555.76038"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8209"
+ y="555.76038"
+ x="575.61847">connected by a dotted line to the ibex_icache_env_cfg class.</tspan><tspan
+ id="tspan8211"
+ y="555.76038"
+ x="1006.2747"
+ dx="0" /></tspan><tspan
+ id="tspan8217"
+ y="575.76038"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8215"
+ y="575.76038"
+ x="575.61847" /></tspan><tspan
+ id="tspan8221"
+ y="595.76038"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8219"
+ y="595.76038"
+ x="575.61847">The virtual sequence object created in the run phase has a </tspan></tspan><tspan
+ id="tspan8225"
+ y="615.76038"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8223"
+ y="615.76038"
+ x="575.61847">p_sequencer handle to the ibex_icache_virtual_sequencer </tspan></tspan><tspan
+ id="tspan8231"
+ y="635.76038"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8227"
+ y="635.76038"
+ x="575.61847">inside the environment (not shown).</tspan><tspan
+ id="tspan8229"
+ y="635.76038"
+ x="829.24347"
+ dx="0" /></tspan><tspan
+ id="tspan8235"
+ y="635.76038"
+ x="575.61847"
+ sodipodi:role="line"><tspan
+ id="tspan8233"
+ y="655.76038"
+ x="575.61847" /></tspan></text>
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffe599;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect2074"
+ width="239.99998"
+ height="430"
+ x="290.5"
+ y="70.5"
+ rx="25"
+ ry="25" />
+ <text
+ id="text2078"
y="103.84506"
- id="text2078"><tspan
- sodipodi:role="line"
- id="tspan2076"
- x="410.48175"
+ x="410.48175"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f18080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="fill:#000000;fill-opacity:1"
y="103.84506"
- style="fill:#000000;fill-opacity:1">ibex_icache_env_cfg</tspan></text>
+ x="410.48175"
+ id="tspan2076"
+ sodipodi:role="line">ibex_icache_env_cfg</tspan></text>
<g
- transform="translate(215.5,-76.5)"
- id="g2086">
- <rect
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect2080"
- width="229.99998"
- height="36.322979"
- x="80"
- y="205.67702"
- ry="10"
- rx="9.999999" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="194.49219"
- y="228.39612"
- id="text2084"><tspan
- sodipodi:role="line"
- id="tspan2082"
- x="194.49219"
- y="228.39612">ibex_icache_core_if</tspan></text>
- </g>
- <g
- id="g2116"
- transform="translate(220.5,-81.5)">
+ id="g2086"
+ transform="translate(215.5,-76.500001)">
<rect
rx="9.999999"
ry="10"
- y="355.67703"
- x="75"
+ y="205.67702"
+ x="80"
height="36.322979"
width="229.99998"
- id="rect2110"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ id="rect2080"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<text
- id="text2114"
- y="378.39615"
- x="189.98438"
+ id="text2084"
+ y="228.39612"
+ x="194.49219"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
- y="378.39615"
- x="189.98438"
- id="tspan2112"
- sodipodi:role="line">ibex_icache_core_agent_cfg</tspan></text>
+ y="228.39612"
+ x="194.49219"
+ id="tspan2082"
+ sodipodi:role="line">ibex_icache_core_if</tspan></text>
</g>
<g
- transform="translate(220.5,-36.5)"
- id="g2124">
+ transform="translate(220.5,-15.177032)"
+ id="g2116">
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect2118"
+ id="rect2110"
width="229.99998"
height="36.322979"
x="75"
@@ -533,300 +374,656 @@
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="189.98438"
y="378.39615"
- id="text2122"><tspan
+ id="text2114"><tspan
sodipodi:role="line"
- id="tspan2120"
+ id="tspan2112"
x="189.98438"
- y="378.39615">ibex_icache_mem_agent_cfg</tspan></text>
+ y="378.39615">ibex_icache_core_agent_cfg</tspan></text>
</g>
<g
- id="g2196"
- transform="translate(215.5,-31.5)">
+ id="g1140">
<rect
rx="9.999999"
ry="10"
- y="205.67702"
- x="80"
+ y="385.5"
+ x="295.5"
height="36.322979"
width="229.99998"
+ id="rect2118"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <text
+ id="text2122"
+ y="408.21912"
+ x="410.48438"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="408.21912"
+ x="410.48438"
+ id="tspan2120"
+ sodipodi:role="line">ibex_icache_mem_agent_cfg</tspan></text>
+ </g>
+ <g
+ transform="translate(215.5,-31.500001)"
+ id="g2196">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect2190"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ width="229.99998"
+ height="36.322979"
+ x="80"
+ y="205.67702"
+ ry="10"
+ rx="9.999999" />
<text
- id="text2194"
- y="228.39612"
- x="194.49219"
+ xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- y="228.39612"
- x="194.49219"
+ x="194.49219"
+ y="228.39612"
+ id="text2194"><tspan
+ sodipodi:role="line"
id="tspan2192"
- sodipodi:role="line">ibex_icache_mem_if</tspan></text>
+ x="194.49219"
+ y="228.39612">ibex_icache_mem_if</tspan></text>
</g>
<g
- id="g2204"
- transform="translate(215.5,13.5)">
+ transform="translate(215.5,13.499999)"
+ id="g2204">
<rect
- rx="9.999999"
- ry="10"
- y="205.67702"
- x="80"
- height="36.322979"
- width="229.99998"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect2198"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ width="229.99998"
+ height="36.322979"
+ x="80"
+ y="205.67702"
+ ry="10"
+ rx="9.999999" />
<text
- id="text2202"
- y="228.39612"
- x="194.49219"
+ xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- y="228.39612"
- x="194.49219"
+ x="194.49219"
+ y="228.39612"
+ id="text2202"><tspan
+ sodipodi:role="line"
id="tspan2200"
- sodipodi:role="line">clk_reset_if</tspan></text>
+ x="194.49219"
+ y="228.39612">clk_reset_if</tspan></text>
</g>
<text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.33333397px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="30.500004"
+ id="text2330"
y="510.5"
- id="text2330"><tspan
- sodipodi:role="line"
+ x="30.5"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="510.5"
+ x="30.5"
id="tspan2328"
- x="30.500004"
- y="525.27972" /></text>
+ sodipodi:role="line" /></text>
<flowRoot
- xml:space="preserve"
+ transform="translate(-49.500001,-36.500001)"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.6667px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
id="flowRoot2332"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- transform="translate(-49.499996,-36.5)"><flowRegion
- id="flowRegion2334"
- style="text-align:start;text-anchor:start"><rect
- id="rect2336"
- width="440"
- height="120"
- x="80"
+ xml:space="preserve"><flowRegion
+ style="text-align:start;text-anchor:start"
+ id="flowRegion2334"><rect
+ style="text-align:start;text-anchor:start"
y="537"
- style="text-align:start;text-anchor:start" /></flowRegion><flowPara
- id="flowPara2338" /></flowRoot> <g
- id="g2521"
- transform="translate(-49.499996,-36.5)">
+ x="80"
+ height="120"
+ width="440"
+ id="rect2336" /></flowRegion><flowPara
+ id="flowPara2338" /></flowRoot>
+ <g
+ transform="translate(-49.500001,63.499999)"
+ id="g2521">
<path
- sodipodi:nodetypes="cccccc"
- d="m 70,447 h 470 l 40,50 V 617 H 70 Z"
- id="path1559"
+ style="fill:#cfe2f3;fill-rule:evenodd;stroke:#000000;stroke-opacity:1"
inkscape:connector-curvature="0"
- style="fill:#cfe2f3;fill-rule:evenodd;stroke:#000000;stroke-opacity:1" />
+ id="path1559"
+ d="m 70,447 h 470 l 40,50 V 617 H 70 Z"
+ sodipodi:nodetypes="cccccc" />
<g
id="g2507">
<text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.33333397px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="90"
+ id="text2326"
y="471.74084"
- id="text2326"><tspan
- sodipodi:role="line"
- id="tspan2324"
- x="90"
- y="471.74084">run_phase:</tspan></text>
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="90"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="471.74084"
+ x="90"
+ id="tspan2324"
+ sodipodi:role="line">run_phase:</tspan></text>
+ <text
+ id="text8251"
y="497.8609"
- id="text8251"><tspan
- sodipodi:role="line"
- x="90"
+ x="90"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.6667px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ id="tspan8241"
y="497.8609"
- id="tspan8241"><tspan
- x="90"
+ x="90"
+ sodipodi:role="line"><tspan
+ id="tspan8239"
y="497.8609"
- id="tspan8239">In the UVM run phase, the dv_base_test class (from which the </tspan></tspan><tspan
- sodipodi:role="line"
- x="90"
+ x="90">In the UVM run phase, the dv_base_test class (from which the </tspan></tspan><tspan
+ id="tspan8245"
y="517.8609"
- id="tspan8245"><tspan
- x="90"
- y="517.8609"
- id="tspan8243">ibex_icache_base_test class derives) creates and runs the sequence </tspan></tspan><tspan
- sodipodi:role="line"
x="90"
+ sodipodi:role="line"><tspan
+ id="tspan8243"
+ y="517.8609"
+ x="90">ibex_icache_base_test class derives) creates and runs the sequence </tspan></tspan><tspan
+ id="tspan8249"
y="537.8609"
- id="tspan8249"><tspan
- x="90"
+ x="90"
+ sodipodi:role="line"><tspan
+ id="tspan8247"
y="537.8609"
- id="tspan8247">named by the +UVM_TEST_SEQ plusarg.</tspan></tspan></text>
+ x="90">named by the +UVM_TEST_SEQ plusarg.</tspan></tspan></text>
</g>
<g
id="g2499">
<rect
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fff3cd;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect2348"
- width="470"
- height="39.940208"
- x="90"
- y="557"
+ ry="15.181121"
rx="20"
- ry="15.181121" />
+ y="557"
+ x="90"
+ height="39.940208"
+ width="470"
+ id="rect2348"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fff3cd;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="324.9772"
+ id="text2352"
y="581.76636"
- id="text2352"><tspan
- sodipodi:role="line"
- id="tspan2350"
+ x="324.9772"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="581.76636"
x="324.9772"
- y="581.76636">ibex_icache_base_vseq</tspan></text>
+ id="tspan2350"
+ sodipodi:role="line">ibex_icache_base_vseq</tspan></text>
</g>
</g>
<text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.66666603px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="575.61847"
+ id="text2356"
y="265.32785"
- id="text2356"><tspan
- sodipodi:role="line"
- id="tspan2354"
- x="575.61847"
+ x="575.61847"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ style="text-align:start;text-anchor:start"
y="265.32785"
- style="text-align:start;text-anchor:start">Legend:</tspan></text>
+ x="575.61847"
+ id="tspan2354"
+ sodipodi:role="line">Legend:</tspan></text>
<path
- style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1, 2;stroke-dashoffset:0;stroke-opacity:1"
- d="m 290.5,105.5 c -15,0 -35,30 -35,30"
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
id="path1998"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cc"
- inkscape:connector-curvature="0"
- id="path2402"
- d="m 290.5,105.5 c -15,0 -35,75 -35,75"
+ d="m 290.5,105.5 c -15,0 -35,30 -35,30"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1, 2;stroke-dashoffset:0;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1, 2;stroke-dashoffset:0;stroke-opacity:1"
- d="m 290.5,105.5 c -15,0 -35,120 -35,120"
- id="path2404"
+ d="m 290.5,105.5 c -15,0 -35,75 -35,75"
+ id="path2402"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
- id="path2406"
- d="m 290.5,105.5 c -15,0 -30,10 -30,10"
+ id="path2404"
+ d="m 290.5,105.5 c -15,0 -35,120 -35,120"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1, 2;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1, 2;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 290.5,105.5 c -15,0 -30,10 -30,10"
+ id="path2406"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
<rect
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#dad2ea;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect2619"
- width="470"
- height="219.99998"
- x="570.5"
- y="10.499996"
+ ry="0"
rx="0"
- ry="0" />
- <rect
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect7655"
- width="180"
- height="150"
- x="840.5"
- y="60.500008" />
- <text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.33333397px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="930.08954"
- y="141.69531"
- id="text7659"><tspan
- sodipodi:role="line"
- x="930.08954"
- y="141.69531"
- id="tspan7970">ICache</tspan></text>
+ y="10.499995"
+ x="570.5"
+ height="219.99998"
+ width="470"
+ id="rect2619"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#dad2ea;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<g
- id="g7675"
- transform="translate(-49.499996,-149)">
- <rect
- y="222"
- x="640"
- height="35"
- width="170"
- id="rect7666"
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fce6ce;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
- <text
- id="text7670"
- y="244.05762"
- x="724.40332"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.33333397px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- xml:space="preserve"><tspan
- y="244.05762"
- x="724.40332"
- id="tspan7668"
- sodipodi:role="line">core_if</tspan></text>
- </g>
- <g
- id="g7683"
- transform="translate(-49.499996,-104)">
+ transform="translate(-49.500001,-149)"
+ id="g7675">
<rect
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fce6ce;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="rect7677"
+ id="rect7666"
width="170"
height="35"
x="640"
y="222" />
<text
xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.33333397px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="724.40332"
y="244.05762"
- id="text7681"><tspan
+ id="text7670"><tspan
sodipodi:role="line"
- id="tspan7679"
+ id="tspan7668"
x="724.40332"
- y="244.05762">mem_if</tspan></text>
+ y="244.05762">core_if</tspan></text>
</g>
<g
- transform="translate(-49.499996,-59)"
- id="g7691">
+ transform="translate(-49.500001,-104)"
+ id="g7683">
<rect
y="222"
x="640"
height="35"
width="170"
- id="rect7685"
+ id="rect7677"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fce6ce;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<text
- id="text7689"
+ id="text7681"
y="244.05762"
x="724.40332"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.33333397px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="244.05762"
x="724.40332"
+ id="tspan7679"
+ sodipodi:role="line">mem_if</tspan></text>
+ </g>
+ <g
+ id="g7691"
+ transform="translate(-49.500001,-59.000001)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fce6ce;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect7685"
+ width="170"
+ height="35"
+ x="640"
+ y="222" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="724.40332"
+ y="244.05762"
+ id="text7689"><tspan
+ sodipodi:role="line"
id="tspan7687"
- sodipodi:role="line">clk_rst_if</tspan></text>
+ x="724.40332"
+ y="244.05762">clk_rst_if</tspan></text>
</g>
<path
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 765.5,90.5 10,-15 v 10 h 50 v -10 l 10,15 -10,15 v -10 h -50 v 10 z"
+ inkscape:connector-curvature="0"
id="path7693"
+ d="m 765.5,90.499999 10,-15 v 10 h 50 v -10 l 10,15 L 825.5,105.5 V 95.499999 h -50 V 105.5 Z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 765.5,135.5 10,-15 v 10 h 50 v -10 l 10,15 -10,15 v -10 h -50 v 10 z"
+ id="path7695"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
- id="path7695"
- d="m 765.5,135.5 10,-15 v 10 h 50 v -10 l 10,15 -10,15 v -10 h -50 v 10 z"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
- d="m 765.5,183 h 70"
id="path7697"
- inkscape:connector-curvature="0" />
+ d="m 765.5,183 h 70"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)" />
<text
- xml:space="preserve"
- style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.33333397px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- x="612.0202"
+ id="text7968"
y="45.608871"
- id="text7968"><tspan
- sodipodi:role="line"
- id="tspan7966"
+ x="612.0202"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="45.608871"
x="612.0202"
- y="45.608871">tb.sv</tspan></text>
+ id="tspan7966"
+ sodipodi:role="line">tb.sv</tspan></text>
+ <g
+ id="g1295">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect7655"
+ width="180"
+ height="150"
+ x="840.5"
+ y="60.500008" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="930.08527"
+ y="109.6452"
+ id="text7659"><tspan
+ sodipodi:role="line"
+ x="930.08527"
+ y="109.6452"
+ id="tspan7970">ICache</tspan></text>
+ <g
+ id="g1040"
+ transform="translate(-7.5000083,5.2941127)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fce6ce;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect1032"
+ width="120.00001"
+ height="24.705883"
+ x="885.5"
+ y="155.79411" />
+ <rect
+ y="150.5"
+ x="880.5"
+ height="24.705883"
+ width="120.00001"
+ id="rect1030"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fce6ce;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fce6ce;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect1028"
+ width="120.00001"
+ height="24.705883"
+ x="875.5"
+ y="145.5" />
+ <rect
+ y="140.5"
+ x="870.5"
+ height="24.705883"
+ width="120.00001"
+ id="rect993"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fce6ce;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <text
+ id="text997"
+ y="157.41055"
+ x="930.11914"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:17.3333px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="157.41055"
+ x="930.11914"
+ id="tspan995"
+ sodipodi:role="line">ecc_if</tspan></text>
+ </g>
+ </g>
+ <g
+ transform="translate(3.9999955)"
+ id="g1065">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect1057"
+ width="209.99998"
+ height="33.164459"
+ x="307.5"
+ y="276.177"
+ ry="10"
+ rx="9.999999" />
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="272.177"
+ x="303.5"
+ height="33.164459"
+ width="209.99998"
+ id="rect1055"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect1053"
+ width="209.99998"
+ height="33.164459"
+ x="299.5"
+ y="268.177"
+ ry="10"
+ rx="9.999999" />
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="264.177"
+ x="295.5"
+ height="33.164459"
+ width="209.99998"
+ id="rect1042"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#f4cccc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <text
+ id="text1046"
+ y="284.96625"
+ x="399.95312"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="284.96625"
+ x="399.95312"
+ id="tspan1044"
+ sodipodi:role="line">ibex_icache_ecc_if</tspan></text>
+ </g>
+ <g
+ id="g1135">
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="444.5"
+ x="311.5"
+ height="33.164459"
+ width="209.99998"
+ id="rect1067"
+ style="color:#000000;font-variation-settings:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" />
+ <rect
+ style="color:#000000;font-variation-settings:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ id="rect1069"
+ width="209.99998"
+ height="33.164459"
+ x="307.5"
+ y="440.5"
+ ry="10"
+ rx="9.999999" />
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="436.5"
+ x="303.5"
+ height="33.164459"
+ width="209.99998"
+ id="rect1071"
+ style="color:#000000;font-variation-settings:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" />
+ <rect
+ style="color:#000000;font-variation-settings:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ id="rect1073"
+ width="209.99998"
+ height="33.164459"
+ x="299.5"
+ y="432.5"
+ ry="10"
+ rx="9.999999" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="403.95312"
+ y="453.28925"
+ id="text1077"><tspan
+ sodipodi:role="line"
+ id="tspan1075"
+ x="403.95312"
+ y="453.28925">ibex_icache_ecc_agent_cfg</tspan></text>
+ </g>
+ <g
+ id="g1188">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#fff2cc;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect1908"
+ width="239.99998"
+ height="430"
+ x="20.5"
+ y="70.5"
+ rx="25"
+ ry="25.000002" />
+ <text
+ id="text1785"
+ y="104.02103"
+ x="140.09052"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:18.6667px;line-height:19.8625px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#f18080;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"
+ transform="scale(1.0069205,0.99312707)"><tspan
+ style="fill:#000000;fill-opacity:1;stroke-width:1px"
+ y="104.02103"
+ x="140.09052"
+ id="tspan1783"
+ sodipodi:role="line">ibex_icache_env</tspan></text>
+ <g
+ id="g1896"
+ transform="translate(-54.500001,-76.5)">
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="205.67702"
+ x="80"
+ height="36.322979"
+ width="229.99998"
+ id="rect1831"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffe599;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <text
+ id="text1789"
+ y="228.39612"
+ x="194.49219"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="228.39612"
+ x="194.49219"
+ id="tspan1787"
+ sodipodi:role="line">ibex_icache_env_cov</tspan></text>
+ </g>
+ <g
+ id="g1901"
+ transform="translate(-54.499971,-72.822968)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffe599;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect1852"
+ width="229.99998"
+ height="36.322979"
+ x="79.999992"
+ y="247"
+ ry="10"
+ rx="9.999999" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="194.98438"
+ y="269.71912"
+ id="text1856"><tspan
+ sodipodi:role="line"
+ id="tspan1854"
+ x="194.98438"
+ y="269.71912">ibex_icache_scoreboard</tspan></text>
+ </g>
+ <g
+ id="g1906"
+ transform="translate(-54.500001,-67.822969)">
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="287"
+ x="80"
+ height="36.322979"
+ width="229.99998"
+ id="rect1876"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffe599;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <text
+ id="text1880"
+ y="309.71912"
+ x="194.98438"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="309.71912"
+ x="194.98438"
+ id="tspan1878"
+ sodipodi:role="line">ibex_icache_virtual_sequencer</tspan></text>
+ </g>
+ <g
+ id="g2036"
+ transform="translate(-49.500001,-16.500001)">
+ <rect
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ id="rect2008"
+ width="229.99998"
+ height="36.322979"
+ x="75"
+ y="355.67703"
+ ry="10"
+ rx="9.999999" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="189.98438"
+ y="378.39615"
+ id="text2012"><tspan
+ sodipodi:role="line"
+ id="tspan2010"
+ x="189.98438"
+ y="378.39615">ibex_icache_core_agent</tspan></text>
+ </g>
+ <g
+ id="g2044"
+ transform="translate(-49.500001,28.499999)">
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="355.67703"
+ x="75"
+ height="36.322979"
+ width="229.99998"
+ id="rect2038"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <text
+ id="text2042"
+ y="378.39615"
+ x="189.98438"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ xml:space="preserve"><tspan
+ y="378.39615"
+ x="189.98438"
+ id="tspan2040"
+ sodipodi:role="line">ibex_icache_mem_agent</tspan></text>
+ </g>
+ <g
+ id="g1154"
+ transform="translate(-270)">
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="444.5"
+ x="311.5"
+ height="33.164459"
+ width="209.99998"
+ id="rect1142"
+ style="color:#000000;font-variation-settings:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" />
+ <rect
+ style="color:#000000;font-variation-settings:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ id="rect1144"
+ width="209.99998"
+ height="33.164459"
+ x="307.5"
+ y="440.5"
+ ry="10"
+ rx="9.999999" />
+ <rect
+ rx="9.999999"
+ ry="10"
+ y="436.5"
+ x="303.5"
+ height="33.164459"
+ width="209.99998"
+ id="rect1146"
+ style="color:#000000;font-variation-settings:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1" />
+ <rect
+ style="color:#000000;font-variation-settings:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#d9ead3;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000;stop-opacity:1"
+ id="rect1148"
+ width="209.99998"
+ height="33.164459"
+ x="299.5"
+ y="432.5"
+ ry="10"
+ rx="9.999999" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:20px;font-family:'Liberation Sans';-inkscape-font-specification:'Liberation Sans';text-align:center;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="403.95312"
+ y="453.28925"
+ id="text1152"><tspan
+ sodipodi:role="line"
+ id="tspan1150"
+ x="403.95312"
+ y="453.28925">ibex_icache_ecc_agent</tspan></text>
+ </g>
+ </g>
</svg>
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env.core b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env.core
index 610367c..e61837e 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env.core
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env.core
@@ -10,6 +10,7 @@
- lowrisc:dv:dv_lib
- lowrisc:dv:ibex_icache_core_agent
- lowrisc:dv:ibex_icache_mem_agent
+ - lowrisc:dv:ibex_icache_ecc_agent
files:
- ibex_icache_env_pkg.sv
- ibex_icache_env_cfg.sv: {is_include_file: true}
@@ -19,13 +20,15 @@
- ibex_icache_env.sv: {is_include_file: true}
- seq_lib/ibex_icache_vseq_list.sv: {is_include_file: true}
- seq_lib/ibex_icache_base_vseq.sv: {is_include_file: true}
- - seq_lib/ibex_icache_sanity_vseq.sv: {is_include_file: true}
- seq_lib/ibex_icache_passthru_vseq.sv: {is_include_file: true}
- seq_lib/ibex_icache_caching_vseq.sv: {is_include_file: true}
- seq_lib/ibex_icache_invalidation_vseq.sv: {is_include_file: true}
- seq_lib/ibex_icache_oldval_vseq.sv: {is_include_file: true}
- seq_lib/ibex_icache_back_line_vseq.sv: {is_include_file: true}
- seq_lib/ibex_icache_many_errors_vseq.sv: {is_include_file: true}
+ - seq_lib/ibex_icache_ecc_vseq.sv: {is_include_file: true}
+ - seq_lib/ibex_icache_combo_vseq.sv: {is_include_file: true}
+ - seq_lib/ibex_icache_reset_vseq.sv: {is_include_file: true}
file_type: systemVerilogSource
targets:
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env.sv
index c2469bc..97f4515 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env.sv
@@ -13,6 +13,9 @@
ibex_icache_core_agent core_agent;
ibex_icache_mem_agent mem_agent;
+ ibex_icache_ecc_agent ecc_tag_agents[];
+ ibex_icache_ecc_agent ecc_data_agents[];
+
// Heartbeat tracking
uvm_callbacks_objection hb_objection;
uvm_heartbeat heartbeat;
@@ -29,9 +32,28 @@
mem_agent = ibex_icache_mem_agent::type_id::create("mem_agent", this);
uvm_config_db#(ibex_icache_mem_agent_cfg)::set(this, "mem_agent*", "cfg", cfg.mem_agent_cfg);
+ // If ECC is enabled, create ECC agents for the RAMs. We have already created config objects for
+ // them (the test called create_ecc_agent_cfgs in its build_phase method), so we just have to
+ // make an agent for each config. In practice, there will be the same number of tag and data
+ // agents, but this code doesn't really care.
+ ecc_tag_agents = new[cfg.ecc_tag_agent_cfgs.size()];
+ for (int unsigned i = 0; i < cfg.ecc_tag_agent_cfgs.size(); i++) begin
+ string tname = $sformatf("ecc_tag_agents[%0d]", i);
+ ecc_tag_agents[i] = ibex_icache_ecc_agent::type_id::create(tname, this);
+ uvm_config_db#(ibex_icache_ecc_agent_cfg)::set(this, {tname, "*"}, "cfg", cfg.ecc_tag_agent_cfgs[i]);
+ end
+ ecc_data_agents = new[cfg.ecc_data_agent_cfgs.size()];
+ for (int unsigned i = 0; i < cfg.ecc_data_agent_cfgs.size(); i++) begin
+ string dname = $sformatf("ecc_data_agents[%0d]", i);
+ ecc_data_agents[i] = ibex_icache_ecc_agent::type_id::create(dname, this);
+ uvm_config_db#(ibex_icache_ecc_agent_cfg)::set(this, {dname, "*"}, "cfg", cfg.ecc_data_agent_cfgs[i]);
+ end
+
hb_objection = new("hb_objection");
heartbeat = new("heartbeat", this, hb_objection);
hb_event = new("hb_event");
+
+ cfg.clk_rst_vif.set_sole_clock();
endfunction
function void connect_phase(uvm_phase phase);
@@ -41,15 +63,37 @@
mem_agent.monitor.analysis_port.connect(scoreboard.mem_fifo.analysis_export);
core_agent.driver.analysis_port.connect(scoreboard.seed_fifo.analysis_export);
end
- if (cfg.is_active && cfg.mem_agent_cfg.is_active && cfg.core_agent_cfg.is_active) begin
- core_agent.driver.analysis_port.connect(mem_agent.sequencer.seed_fifo.analysis_export);
- end
- if (cfg.is_active && cfg.core_agent_cfg.is_active) begin
- virtual_sequencer.core_sequencer_h = core_agent.sequencer;
- end
- if (cfg.is_active && cfg.mem_agent_cfg.is_active) begin
- virtual_sequencer.mem_sequencer_h = mem_agent.sequencer;
+ // If we are active, wire up each active agent to a sequencer in the virtual sequencer.
+ if (cfg.is_active) begin
+ if (cfg.mem_agent_cfg.is_active && cfg.core_agent_cfg.is_active) begin
+ core_agent.driver.analysis_port.connect(mem_agent.sequencer.seed_fifo.analysis_export);
+ end
+
+ if (cfg.core_agent_cfg.is_active) begin
+ virtual_sequencer.core_sequencer_h = core_agent.sequencer;
+ end
+ if (cfg.mem_agent_cfg.is_active) begin
+ virtual_sequencer.mem_sequencer_h = mem_agent.sequencer;
+ end
+
+ // We assume that either all ECC tag/data agents are active or none of them are.
+ `DV_CHECK_EQ_FATAL(cfg.ecc_tag_agent_cfgs.size(), ecc_tag_agents.size())
+ if ((cfg.ecc_tag_agent_cfgs.size() > 0) && (cfg.ecc_tag_agent_cfgs[0].is_active)) begin
+ virtual_sequencer.ecc_tag_sequencers = new[cfg.ecc_tag_agent_cfgs.size()];
+ foreach (ecc_tag_agents[i]) begin
+ `DV_CHECK_FATAL(cfg.ecc_tag_agent_cfgs[i].is_active);
+ virtual_sequencer.ecc_tag_sequencers[i] = ecc_tag_agents[i].sequencer;
+ end
+ end
+ `DV_CHECK_EQ_FATAL(cfg.ecc_data_agent_cfgs.size(), ecc_data_agents.size())
+ if ((cfg.ecc_data_agent_cfgs.size() > 0) && (cfg.ecc_data_agent_cfgs[0].is_active)) begin
+ virtual_sequencer.ecc_data_sequencers = new[cfg.ecc_data_agent_cfgs.size()];
+ foreach (ecc_data_agents[i]) begin
+ `DV_CHECK_FATAL(cfg.ecc_data_agent_cfgs[i].is_active);
+ virtual_sequencer.ecc_data_sequencers[i] = ecc_data_agents[i].sequencer;
+ end
+ end
end
// Register the heartbeat objection with both sequencers (so they know how to reset it)
@@ -69,8 +113,8 @@
// is triggered.
heartbeat.start(hb_event);
forever begin
- // Every 2000 clocks, check the heartbeat monitor
- cfg.core_agent_cfg.vif.wait_clks(2000);
+ // Every 2000 clocks, check the heartbeat monitor (not stopping early on reset)
+ cfg.core_agent_cfg.vif.wait_clks(2000, 1'b0);
hb_event.trigger();
end
endtask
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env_cfg.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env_cfg.sv
index c531553..19b67f5 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env_cfg.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env_cfg.sv
@@ -4,13 +4,30 @@
class ibex_icache_env_cfg extends dv_base_env_cfg;
+ // If set, the scoreboard won't check caching ratios
+ bit disable_caching_ratio_test = 0;
+
// ext component cfgs
rand ibex_icache_core_agent_cfg core_agent_cfg;
rand ibex_icache_mem_agent_cfg mem_agent_cfg;
+ // Force the clock frequency to 50MHz. The clock frequency doesn't really matter for ICache
+ // testing and 50MHz dumped waves are nice to read because clock edges are multiples of 10ns.
+ constraint clk_freq_50_c {
+ clk_freq_mhz == ClkFreq50Mhz;
+ }
+
+ // Config objects for ECC components (see create_ecc_agent_cfgs). Since these are created after
+ // initialization, they won't get randomized automatically, so we do that manually at the bottom
+ // of create_ecc_agent_cfgs.
+ ibex_icache_ecc_agent_cfg ecc_tag_agent_cfgs[];
+ ibex_icache_ecc_agent_cfg ecc_data_agent_cfgs[];
+
`uvm_object_utils_begin(ibex_icache_env_cfg)
- `uvm_field_object(core_agent_cfg, UVM_DEFAULT)
- `uvm_field_object(mem_agent_cfg, UVM_DEFAULT)
+ `uvm_field_object (core_agent_cfg, UVM_DEFAULT)
+ `uvm_field_object (mem_agent_cfg, UVM_DEFAULT)
+ `uvm_field_array_object(ecc_tag_agent_cfgs, UVM_DEFAULT)
+ `uvm_field_array_object(ecc_data_agent_cfgs, UVM_DEFAULT)
`uvm_object_utils_end
`uvm_object_new
@@ -20,4 +37,20 @@
mem_agent_cfg = ibex_icache_mem_agent_cfg::type_id::create ("mem_agent_cfg");
endfunction
+ // Create tag and data ECC agents for each way. If ECC is disabled, this should still be called,
+ // but with num_ecc_ways = 0.
+ function automatic void create_ecc_agent_cfgs(int unsigned num_ecc_ways);
+ ecc_tag_agent_cfgs = new[num_ecc_ways];
+ ecc_data_agent_cfgs = new[num_ecc_ways];
+ for (int unsigned i = 0; i < num_ecc_ways; i++) begin
+ string tname = $sformatf("ecc_tag_agent_cfgs[%0d]", i);
+ string dname = $sformatf("ecc_data_agent_cfgs[%0d]", i);
+ ecc_tag_agent_cfgs[i] = ibex_icache_ecc_agent_cfg::type_id::create(tname);
+ ecc_data_agent_cfgs[i] = ibex_icache_ecc_agent_cfg::type_id::create(dname);
+
+ `DV_CHECK_RANDOMIZE_FATAL(ecc_tag_agent_cfgs[i])
+ `DV_CHECK_RANDOMIZE_FATAL(ecc_data_agent_cfgs[i])
+ end
+ endfunction
+
endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env_pkg.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env_pkg.sv
index 1bc056a..b897261 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env_pkg.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_env_pkg.sv
@@ -9,6 +9,7 @@
import dv_utils_pkg::*;
import ibex_icache_core_agent_pkg::*;
import ibex_icache_mem_agent_pkg::*;
+ import ibex_icache_ecc_agent_pkg::*;
import dv_lib_pkg::*;
// macro includes
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv
index b7c147f..2ce093c 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_scoreboard.sv
@@ -26,7 +26,7 @@
ibex_icache_mem_model #(BusWidth) mem_model;
// A queue of memory seeds.
- bit [31:0] mem_seeds[$];
+ bit [31:0] mem_seeds[$] = {32'd0};
// Tracks the next address we expect to see on a fetch. This gets reset to 'X, then is set to an
// address after each branch transaction.
@@ -119,17 +119,17 @@
seed_fifo = new("seed_fifo", this);
mem_model = new("mem_model",
cfg.mem_agent_cfg.disable_pmp_errs,
- cfg.mem_agent_cfg.disable_mem_errs,
- cfg.mem_agent_cfg.mem_err_shift);
+ cfg.mem_agent_cfg.disable_mem_errs);
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
- window_reset();
+ tracking_reset();
fork
process_core_fifo();
process_mem_fifo();
process_seed_fifo();
+ monitor_negedge_reset();
join_none
endtask
@@ -205,6 +205,9 @@
mem_fifo.get(item);
`uvm_info(`gfn, $sformatf("received mem transaction:\n%0s", item.sprint()), UVM_HIGH)
+ // Looks like we are in reset. Discard the item.
+ if (!cfg.clk_rst_vif.rst_n) continue;
+
if (item.is_grant) begin
mem_trans_count += 1;
window_take_mem_read();
@@ -225,10 +228,31 @@
end
endtask
- virtual function void reset(string kind = "HARD");
- super.reset(kind);
+ // Trigger start_reset on every negedge of the reset line. Never returns.
+ task monitor_negedge_reset();
+ forever begin
+ @(negedge cfg.clk_rst_vif.rst_n) start_reset();
+ end
+ endtask
+
+ // A function called on negedge of rst_n
+ function void start_reset();
next_addr = 'X;
- mem_seeds = {32'd0};
+
+ // Throw away any old seeds
+ invalidate_seed = mem_seeds.size - 1;
+ mem_seeds = mem_seeds[invalidate_seed:$];
+ invalidate_seed = 0;
+ last_branch_seed = 0;
+
+ // Forget about any pending bus transactions (they've been thrown away anyway)
+ mem_trans_count = 0;
+ endfunction
+
+ // Called on the posedge of rst_n which ends the reset period.
+ function void reset(string kind = "HARD");
+ super.reset(kind);
+ tracking_reset();
endfunction
function void check_phase(uvm_phase phase);
@@ -260,7 +284,7 @@
if (chatty) begin
`uvm_info(`gfn,
$sformatf("Not seed 0x%08h: expected seen_err but saw 0.", seed),
- UVM_MEDIUM)
+ UVM_LOW)
end
return 0;
end
@@ -276,7 +300,7 @@
if (chatty) begin
`uvm_info(`gfn,
$sformatf("Not seed 0x%08h: got unexpected error flag.", seed),
- UVM_MEDIUM)
+ UVM_LOW)
end
return 0;
end
@@ -289,7 +313,7 @@
$sformatf("Not seed 0x%08h (expected cmp 0x(%04h)%04h; saw 0x(%04h)%04h).",
seed, exp_insn_data[31:16], exp_insn_data[15:0],
seen_insn_data[31:16], seen_insn_data[15:0]),
- UVM_MEDIUM)
+ UVM_LOW)
end
return 0;
end
@@ -299,7 +323,7 @@
`uvm_info(`gfn,
$sformatf("Not seed 0x%08h (expected uncomp 0x%08h; saw 0x%08h).",
seed, exp_insn_data, seen_insn_data),
- UVM_MEDIUM)
+ UVM_LOW)
end
return 0;
end
@@ -334,7 +358,7 @@
`uvm_info(`gfn,
$sformatf("Not seeds 0x%08h/0x%08h (expected error in low word).",
seed_lo, seed_hi),
- UVM_MEDIUM)
+ UVM_LOW)
end
return 0;
end
@@ -344,7 +368,7 @@
`uvm_info(`gfn,
$sformatf("Not seeds 0x%08h/0x%08h (exp/seen top errors %0d/%0d).",
seed_lo, seed_hi, exp_err_hi, seen_err_plus2),
- UVM_MEDIUM)
+ UVM_LOW)
end
return 0;
end
@@ -354,7 +378,7 @@
`uvm_info(`gfn,
$sformatf("Match for seeds 0x%08h/0x%08h (seen upper error).",
seed_lo, seed_hi),
- UVM_MEDIUM)
+ UVM_LOW)
end
return 1'b1;
end
@@ -365,7 +389,7 @@
`uvm_info(`gfn,
$sformatf("Not seeds 0x%08h/0x%08h (exp/seen data 0x%08h/0x%08h).",
seed_lo, seed_hi, exp_insn_data, seen_insn_data),
- UVM_MEDIUM)
+ UVM_LOW)
end
return 0;
end
@@ -406,7 +430,8 @@
return is_fetch_compatible_1(seen_insn_data,
seen_err,
- mem_model.is_either_error(seed, addr_lo),
+ mem_model.is_either_error(seed, addr_lo,
+ cfg.mem_agent_cfg.mem_err_shift),
rdata[31:0],
seed,
chatty);
@@ -445,13 +470,13 @@
lo_bits_to_drop = BusWidth - lo_bits_to_take;
// Do the first read (from the low address) and shift right to drop the bits that we don't need.
- exp_err_lo = mem_model.is_either_error(seed_lo, addr_lo);
+ exp_err_lo = mem_model.is_either_error(seed_lo, addr_lo, cfg.mem_agent_cfg.mem_err_shift);
rdata = mem_model.read_data(seed_lo, addr_lo) >> lo_bits_to_drop;
exp_data = rdata[31:0];
// Now do the second read (from the upper address). Shift the result up by lo_bits_to_take,
// which will discard some top bits. Then extract 32 bits and OR with what we have so far.
- exp_err_hi = mem_model.is_either_error(seed_hi, addr_hi);
+ exp_err_hi = mem_model.is_either_error(seed_hi, addr_hi, cfg.mem_agent_cfg.mem_err_shift);
rdata = mem_model.read_data(seed_hi, addr_hi) << lo_bits_to_take;
exp_data = exp_data | rdata[31:0];
@@ -587,11 +612,17 @@
end
endtask
+ // Completely reset cache tracking, waiting for busy to drop to be certain that invalidation is
+ // done
+ function automatic void tracking_reset();
+ not_invalidating = 1'b0;
+ window_reset();
+ endfunction
+
// Reset the caching tracking window
function automatic void window_reset();
insns_in_window = 0;
reads_in_window = 0;
- not_invalidating = 1'b0;
window_range_lo = ~(31'b0);
window_range_hi = 0;
endfunction
@@ -604,10 +635,16 @@
// Register an instruction fetch with the caching tracking window
function automatic void window_take_insn(bit [31:0] addr, bit err);
- bit [31:0] window_width;
+ bit [32:0] window_width;
int unsigned fetch_ratio_pc;
- if (err) begin
+ // Ignore instructions and reset the window if this check is disabled in the configuration.
+ // Resetting the window each time avoids cases where we run an ECC sequence for a while (where
+ // the check should be disabled), then switch to a normal sequence (where the check should be
+ // enabled) just before the window finishes.
+ //
+ // Similarly, bail on an error since that would significantly lower the cache hit ratio.
+ if (err || cfg.disable_caching_ratio_test) begin
window_reset();
return;
end
@@ -625,14 +662,14 @@
// We have a full window. Has the address range been sufficiently small? The fatal check is for
// the scoreboard logic: this should hold true as soon as we've seen an instruction.
`DV_CHECK_LE_FATAL(window_range_lo, window_range_hi);
- window_width = (window_range_hi - window_range_lo + 3) / 4;
+ window_width = ({1'b0, window_range_hi} - {1'b0, window_range_lo} + 33'd3) / 4;
`uvm_info(`gfn,
$sformatf("Completed window with %0d insns and %0d reads, range [0x%08h, 0x%08h].",
insns_in_window, reads_in_window, window_range_lo, window_range_hi),
UVM_HIGH)
- if (window_width <= max_window_width) begin
+ if (window_width[31:0] <= max_window_width) begin
// The range has been small enough, so we can actually check whether the caching is working.
// Calculate the R we've seen (as a percentage).
fetch_ratio_pc = (reads_in_window * 100 * 7 / 4) / insns_in_window;
@@ -643,7 +680,7 @@
"%0d instructions and address range [0x%08h, 0x%08h] ",
"(window width %0d)"},
fetch_ratio_pc, insns_in_window,
- window_range_lo, window_range_hi, window_width))
+ window_range_lo, window_range_hi, window_width[31:0]))
end
// Start the next window
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_virtual_sequencer.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_virtual_sequencer.sv
index 32a1e8e..c5c5e05 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_virtual_sequencer.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/ibex_icache_virtual_sequencer.sv
@@ -9,6 +9,9 @@
ibex_icache_core_sequencer core_sequencer_h;
ibex_icache_mem_sequencer mem_sequencer_h;
+ ibex_icache_ecc_sequencer ecc_tag_sequencers[];
+ ibex_icache_ecc_sequencer ecc_data_sequencers[];
+
`uvm_component_new
endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_back_line_vseq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_back_line_vseq.sv
index dac4210..b016b9c 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_back_line_vseq.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_back_line_vseq.sv
@@ -8,12 +8,27 @@
`uvm_object_new
virtual task pre_start();
+ uvm_factory f;
+ uvm_object_wrapper wrapper;
+ string base_name, back_name, old_name, inst_path;
+
// The base class creates a sequence for the core and memory agents in its pre_start method. We
- // want to override its decision and use a different sequence for the core
- ibex_icache_core_base_seq::type_id::
- set_inst_override(ibex_icache_core_back_line_seq::get_type(), "*");
+ // want to override its decision and use a different sequence for the core. To do so, we use the
+ // factory's set_inst_override_by_name. Once we've called the base class's pre_start method, we
+ // tidy up the override again (to allow sequence chaining).
+ f = uvm_factory::get();
+ base_name = ibex_icache_core_base_seq::type_name;
+ back_name = ibex_icache_core_back_line_seq::type_name;
+ inst_path = {`gfn, ".*"};
+
+ wrapper = f.find_override_by_name(base_name, inst_path);
+ old_name = (wrapper == null) ? base_name : wrapper.get_type_name();
+ f.set_inst_override_by_name(base_name, back_name, inst_path);
super.pre_start();
+
+ f.set_inst_override_by_name(base_name, old_name, inst_path);
+
endtask : pre_start
endclass : ibex_icache_back_line_vseq
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_base_vseq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_base_vseq.sv
index e6c5288..6398e9e 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_base_vseq.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_base_vseq.sv
@@ -11,41 +11,111 @@
`uvm_object_utils(ibex_icache_base_vseq)
`uvm_object_new
- // The two actual sequences. We don't subclass them in subclasses of this virtual sequence, but we
- // might want to set control knobs. To allow this, we construct the sequences in pre_start.
+ // Should we generate ECC errors in the underlying SRAM objects?
+ bit enable_ecc_errors = 0;
+
+ // The mem_err_shift parameter to use for the memory model with this sequence. Gets written to the
+ // sequencer's config when the sequence runs.
+ int unsigned mem_err_shift = 3;
+
+ // Non-null if this is an item after the first in a "combo" run, which runs several of these
+ // sequences back-to-back. Must be set before pre_start to have any effect.
+ ibex_icache_base_vseq prev_sequence = null;
+
+ // The core and memory sequences. We don't subclass them in subclasses of this virtual sequence,
+ // but we might want to set control knobs. To allow this, we construct the sequences in pre_start.
// Subclasses should override pre_start, call this super to construct the sequence, and then set
// any control knobs they need.
ibex_icache_core_base_seq core_seq;
ibex_icache_mem_resp_seq mem_seq;
- virtual task dut_init(string reset_kind = "HARD");
- super.dut_init();
- endtask
+ // ECC sequences. The arrays are created in pre_start and are nonempty if ECC errors are enabled.
+ ibex_icache_ecc_base_seq ecc_tag_seqs[];
+ ibex_icache_ecc_base_seq ecc_data_seqs[];
+
+ // The number of transactions to run (passed to the core sequence). This gets randomised to
+ // something sensible by default, but can be overridden by setting it before starting the
+ // sequence.
+ constraint num_trans_c { num_trans inside {[800:1000]}; }
virtual task pre_start();
super.pre_start();
+
`uvm_create_on(core_seq, p_sequencer.core_sequencer_h)
`uvm_create_on(mem_seq, p_sequencer.mem_sequencer_h)
+
+ // Unlike the other sequences, the core sequence has a finite number of items. Set that to our
+ // number of transactions here.
+ core_seq.num_trans = num_trans;
+
+ if (prev_sequence != null) begin
+ // If there was a previous sequence, pass it down to core_seq and mem_seq
+ core_seq.prev_sequence = prev_sequence.core_seq;
+ mem_seq.prev_sequence = prev_sequence.mem_seq;
+
+ // If the new memory sequence will change mem_err_shift, we need to tell the core to
+ // invalidate at the start of its sequence.
+ if (cfg.mem_agent_cfg.mem_err_shift != mem_err_shift) begin
+ core_seq.must_invalidate = 1'b1;
+ end
+ end
+
+ // Write mem_err_shift into the config object (which the scoreboard and memory sequence will
+ // both see)
+ cfg.mem_agent_cfg.mem_err_shift = mem_err_shift;
+
+ // If enable_ecc_errors then create any ECC sequences we need (one for each sequencer in
+ // p_sequencer.ecc_tag_sequencers and p_sequencer.ecc_data_sequencers).
+ ecc_tag_seqs = new[enable_ecc_errors ? p_sequencer.ecc_tag_sequencers.size() : 0];
+ foreach (ecc_tag_seqs[i]) begin
+ `uvm_create_on(ecc_tag_seqs[i], p_sequencer.ecc_tag_sequencers[i])
+ end
+ ecc_data_seqs = new[enable_ecc_errors ? p_sequencer.ecc_data_sequencers.size() : 0];
+ foreach (ecc_data_seqs[i]) begin
+ `uvm_create_on(ecc_data_seqs[i], p_sequencer.ecc_data_sequencers[i])
+ end
endtask : pre_start
virtual task body();
- // Start the core and memory sequences. We use fork/join_any so that we don't wait for the
- // memory sequence (which is reactive so will never finish).
fork
+ // The core sequence blocks until it has run all its items.
begin
`DV_CHECK_RANDOMIZE_FATAL(core_seq)
core_seq.start(p_sequencer.core_sequencer_h);
end
- begin
- `DV_CHECK_RANDOMIZE_FATAL(mem_seq)
- mem_seq.start(p_sequencer.mem_sequencer_h);
- end
+
+ // These sequences will never end. We wrap them all up together in a fork/join so that we can
+ // fork/join_none any ECC sequences (which yield immediately so that we can start them in a
+ // loop), but still have a process that never yields, to use as a child for the surrounding
+ // fork/join_any.
+ fork
+ begin
+ `DV_CHECK_RANDOMIZE_FATAL(mem_seq)
+ mem_seq.start(p_sequencer.mem_sequencer_h);
+ end
+ foreach (ecc_tag_seqs[i]) begin
+ start_ecc_body(ecc_tag_seqs[i], p_sequencer.ecc_tag_sequencers[i]);
+ end
+ foreach (ecc_data_seqs[i]) begin
+ start_ecc_body(ecc_data_seqs[i], p_sequencer.ecc_data_sequencers[i]);
+ end
+ join
join_any
+
+ // The core sequence has finished. Kill all the other sequences
+ mem_seq.kill();
+ foreach (ecc_tag_seqs[i]) ecc_tag_seqs[i].kill();
+ foreach (ecc_data_seqs[i]) ecc_data_seqs[i].kill();
+
endtask : body
- virtual task dut_shutdown();
- // check for pending ibex_icache operations and wait for them to complete
- // TODO
+ // Randomize and then run a given (never ending) ECC sequence on the given sequencer. Returns
+ // immediately (so you can start sequences in a loop).
+ protected task start_ecc_body(ibex_icache_ecc_base_seq seq, ibex_icache_ecc_sequencer sqr);
+ `DV_CHECK_RANDOMIZE_FATAL(seq);
+ fork begin
+ seq.start(sqr);
+ end join_none
endtask
endclass : ibex_icache_base_vseq
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_combo_vseq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_combo_vseq.sv
new file mode 100644
index 0000000..3eb0c9e
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_combo_vseq.sv
@@ -0,0 +1,128 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// A "combination vseq", which runs proper virtual sequences in a random order.
+
+class ibex_icache_combo_vseq
+ extends dv_base_vseq #(
+ .CFG_T (ibex_icache_env_cfg),
+ .COV_T (ibex_icache_env_cov),
+ .VIRTUAL_SEQUENCER_T (ibex_icache_virtual_sequencer)
+ );
+ `uvm_object_utils(ibex_icache_combo_vseq)
+ `uvm_object_new
+
+ // The number of transactions across the combined sequences
+ constraint num_trans_c { num_trans inside {[800:1000]}; }
+
+ // The virtual sequences from which we'll build the test. Note that this doesn't contain
+ // "ibex_icache_oldval_vseq": that sequence is for a specific test, which has a slightly different
+ // checker.
+ string seq_names[] = {"ibex_icache_back_line_vseq",
+ "ibex_icache_base_vseq", // for sanity test
+ "ibex_icache_caching_vseq",
+ "ibex_icache_ecc_vseq",
+ "ibex_icache_invalidation_vseq",
+ "ibex_icache_many_errors_vseq",
+ "ibex_icache_passthru_vseq"};
+
+ // If this is set, occasionally reset the DUT and start a new sequence at a time that the core
+ // sequence wouldn't normally expect.
+ bit random_reset = 1'b0;
+
+ // How many sequences have we executed so far?
+ int unsigned seqs_so_far = 0;
+
+ // The child (virtual) sequence
+ ibex_icache_base_vseq child_seq;
+
+ // The previous sequence that we ran.
+ ibex_icache_base_vseq prev_seq = null;
+
+ task body();
+ int unsigned trans_so_far = 0;
+
+ while (trans_so_far < num_trans) begin
+ int unsigned seq_idx;
+ uvm_sequence seq;
+ int unsigned trans_now;
+ bit should_reset;
+
+ seq_idx = $urandom_range(0, seq_names.size - 1);
+
+ // Pick the number of transactions to run. We don't want too many, because the whole point is
+ // that we're interested in the edges between sequences. Note that we don't bother to ensure
+ // that trans_so_far + trans_now <= num_trans: it won't really matter if we overshoot by a
+ // little.
+ trans_now = $urandom_range(50, 100);
+
+ // We don't need to reset if seq_idx == 0 (because we did a reset before starting this task).
+ // Otherwise, we always reset between sequences if random_reset is true. We'd always need to
+ // if we killed the previous sequence, and it's easier not to bother tracking properly. If
+ // random_reset is false (the usual back-to-back sequence test), we reset 1 time in 2.
+ if (seq_idx == 0) should_reset = 1'b0;
+ else if (random_reset) should_reset = 1'b1;
+ else should_reset = $urandom_range(0, 1);
+
+ `uvm_info(`gfn,
+ $sformatf("Running sequence '%s' (%0d transactions; reset=%0d).",
+ seq_names[seq_idx], trans_now, should_reset),
+ UVM_HIGH)
+
+ seq = create_seq_by_name(seq_names[seq_idx]);
+ `downcast(child_seq, seq)
+
+ child_seq.set_sequencer(p_sequencer);
+ `DV_CHECK_RANDOMIZE_FATAL(child_seq)
+
+ child_seq.num_trans = trans_now;
+ child_seq.do_dut_init = should_reset;
+ child_seq.prev_sequence = prev_seq;
+
+ // The memory agent is careful to avoid consuming requests from its sequencer's request_fifo
+ // until it has handled them. This is important if we're not resetting (it essentially allows
+ // the sequence to change under the feet of the rest of the environment without it noticing),
+ // but we need to make sure we discard any pending requests on an actual reset. Do that here.
+ if (should_reset && seqs_so_far > 0) begin
+ p_sequencer.mem_sequencer_h.request_fifo.flush();
+ end
+
+ run_sequence();
+
+ prev_seq = child_seq;
+ trans_so_far += trans_now;
+ seqs_so_far += 1;
+ end
+ endtask : body
+
+ // Run a sequence. If random_reset = 0, this will run to completion. Otherwise, the sequence may
+ // be stopped early.
+ protected task run_sequence();
+ int unsigned cycles_till_reset;
+ bit reached_timeout = 1'b0;
+
+ if (!random_reset) begin
+ child_seq.start(p_sequencer, this);
+ end else begin
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(cycles_till_reset,
+ cycles_till_reset dist {
+ [100:500] :/ 1,
+ [501:1000] :/ 4
+ };)
+ fork
+ child_seq.start(p_sequencer, this);
+ begin
+ repeat (cycles_till_reset) @(cfg.clk_rst_vif.cb);
+ reached_timeout = 1'b1;
+ end
+ join_any
+ end
+
+ if (reached_timeout) child_seq.kill();
+
+ // Kill the timer process if it's still going.
+ disable fork;
+ endtask : run_sequence
+
+endclass : ibex_icache_combo_vseq
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_ecc_vseq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_ecc_vseq.sv
new file mode 100644
index 0000000..ed5340c
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_ecc_vseq.sv
@@ -0,0 +1,33 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// A sequence that injects ECC errors and checks we deal with them correctly.
+//
+// This is based on the caching vseq, which means we should see lots of cache hits (some of which
+// will be corrupt).
+
+class ibex_icache_ecc_vseq extends ibex_icache_caching_vseq;
+
+ `uvm_object_utils(ibex_icache_ecc_vseq)
+ `uvm_object_new
+
+ virtual task pre_start();
+ enable_ecc_errors = 1'b1;
+ super.pre_start();
+ endtask : pre_start
+
+ // Wrap the underlying body, setting the disable_caching_ratio_test flag to tell the scoreboard
+ // not to track cache hit ratios. This test corrupts data in the ICache's memory. The corruptions
+ // are spotted, and behave as if the cache missed. This (obviously) lowers the cache hit rate, so
+ // we don't want the test to make sure it's high enough.
+ virtual task body();
+ bit old_dcrt = p_sequencer.cfg.disable_caching_ratio_test;
+ p_sequencer.cfg.disable_caching_ratio_test = 1'b1;
+
+ super.body();
+
+ p_sequencer.cfg.disable_caching_ratio_test = old_dcrt;
+ endtask : body
+
+endclass : ibex_icache_ecc_vseq
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_many_errors_vseq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_many_errors_vseq.sv
index 051d054..65ad763 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_many_errors_vseq.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_many_errors_vseq.sv
@@ -5,7 +5,14 @@
class ibex_icache_many_errors_vseq extends ibex_icache_base_vseq;
`uvm_object_utils(ibex_icache_many_errors_vseq)
- `uvm_object_new
+
+ function new (string name="");
+ super.new(name);
+
+ // Increase the error rate (to roughly 50%) for this sequence.
+ mem_err_shift = 1;
+
+ endfunction : new
virtual task pre_start();
super.pre_start();
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_reset_vseq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_reset_vseq.sv
new file mode 100644
index 0000000..14526ad
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_reset_vseq.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
+
+// A version of the combination vseq that injects resets at unexpected times.
+
+class ibex_icache_reset_vseq extends ibex_icache_combo_vseq;
+
+ `uvm_object_utils(ibex_icache_reset_vseq)
+ `uvm_object_new
+
+ task pre_do (bit is_item);
+ super.pre_do(is_item);
+
+ // Enable "random reset" functionality, which resets the DUT (and starts a new sequence) at
+ // random times.
+ random_reset = 1'b1;
+ endtask : pre_do
+
+endclass : ibex_icache_reset_vseq
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_sanity_vseq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_sanity_vseq.sv
deleted file mode 100644
index 8e8a07e..0000000
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_sanity_vseq.sv
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-// Basic sanity test
-
-class ibex_icache_sanity_vseq extends ibex_icache_base_vseq;
-
- `uvm_object_utils(ibex_icache_sanity_vseq)
- `uvm_object_new
-
- // No customisation of base class needed
-
-endclass : ibex_icache_sanity_vseq
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_vseq_list.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_vseq_list.sv
index 846e351..ed24e24 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_vseq_list.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/env/seq_lib/ibex_icache_vseq_list.sv
@@ -3,10 +3,12 @@
// SPDX-License-Identifier: Apache-2.0
`include "ibex_icache_base_vseq.sv"
-`include "ibex_icache_sanity_vseq.sv"
`include "ibex_icache_passthru_vseq.sv"
`include "ibex_icache_caching_vseq.sv"
`include "ibex_icache_invalidation_vseq.sv"
`include "ibex_icache_oldval_vseq.sv"
`include "ibex_icache_back_line_vseq.sv"
`include "ibex_icache_many_errors_vseq.sv"
+`include "ibex_icache_ecc_vseq.sv"
+`include "ibex_icache_combo_vseq.sv"
+`include "ibex_icache_reset_vseq.sv"
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_driver.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_driver.sv
index 689145f..8f70897 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_driver.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_driver.sv
@@ -59,12 +59,30 @@
// Drive the enable state
cfg.vif.driver_cb.enable <= req.enable;
+ // Maybe drive the ready line high while the branch happens. This should have no effect, but is
+ // allowed by the interface so we should make sure it happens occasionally. The signal will be
+ // controlled properly by read_insns afterwards.
+ cfg.vif.driver_cb.ready <= $urandom_range(16) == 0;
+
+ // Branch, invalidate and set new seed immediately. When the branch has finished, read num_insns
+ // instructions and wiggle the branch_spec line until everything is done.
fork
+ begin
cfg.vif.branch_to(req.branch_addr);
- if (req.invalidate) invalidate();
- if (req.new_seed != 0) drive_new_seed(req.new_seed);
- read_insns(rsp, req.num_insns);
+ cfg.vif.driver_cb.ready <= 1'b0;
+ fork
+ read_insns(rsp, req.num_insns);
+ drive_branch_spec();
+ join_any
+ end
+ if (req.invalidate) invalidate();
+ if (req.new_seed != 0) drive_new_seed(req.new_seed);
join
+
+ // Kill the drive_branch_spec process and reset branch_spec if necessary.
+ disable fork;
+ cfg.vif.driver_cb.branch_spec <= 0;
+
endtask
// Drive the cache for a "req transaction".
@@ -89,12 +107,24 @@
// Drive the enable state
cfg.vif.driver_cb.enable <= req.enable;
+ // Lower req, invalidate and set new seed immediately. After req_low_cycles cycles, start
+ // reading instructions (providing there hasn't been a reset). Wiggle the branch_spec line the
+ // whole time.
fork
- if (req_low_cycles > 0) lower_req(req_low_cycles);
- if (req.invalidate) invalidate();
- if (req.new_seed != 0) drive_new_seed(req.new_seed);
- join
- read_insns(rsp, req.num_insns);
+ begin
+ fork
+ if (req_low_cycles > 0) lower_req(req_low_cycles);
+ if (req.invalidate) invalidate();
+ if (req.new_seed != 0) drive_new_seed(req.new_seed);
+ join
+ if (cfg.vif.rst_n) read_insns(rsp, req.num_insns);
+ end
+ drive_branch_spec();
+ join_any
+
+ // Kill the drive_branch_spec process and reset branch_spec if necessary.
+ disable fork;
+ cfg.vif.driver_cb.branch_spec <= 0;
endtask
// Read up to num_insns instructions from the cache, stopping early on an error. If there was an
@@ -107,6 +137,16 @@
rsp.saw_error = 1'b1;
break;
end
+ // Return early on reset
+ if (!cfg.vif.rst_n) break;
+ end
+ endtask
+
+ // Randomly drive the branch_spec line one cycle in 64. Never returns.
+ task automatic drive_branch_spec();
+ forever begin
+ cfg.vif.driver_cb.branch_spec <= $urandom_range(64) == 0;
+ @(cfg.vif.driver_cb);
end
endtask
@@ -114,30 +154,34 @@
virtual task automatic read_insn();
int unsigned delay;
- // Maybe (1 time in 10) wait for a valid signal before even considering asserting ready.
- if ($urandom_range(9) == 0)
- wait (cfg.vif.driver_cb.valid);
+ // Maybe (1 time in 10) wait for a valid signal before even considering asserting ready. Stops
+ // early on reset.
+ if ($urandom_range(9) == 0) begin
+ cfg.vif.wait_valid();
+ if (!cfg.vif.rst_n)
+ return;
+ end
// Then pick how long we wait before asserting that we are ready.
//
// TODO: Make this configurable and weight 0 more heavily.
cfg.vif.wait_clks($urandom_range(3));
- // Assert ready and then wait until valid
+ // Assert ready and then wait until valid. If we see a reset, we stop early
cfg.vif.driver_cb.ready <= 1'b1;
while (1'b1) begin
- @(cfg.vif.driver_cb);
- if (cfg.vif.driver_cb.valid)
+ @(cfg.vif.driver_cb or negedge cfg.vif.rst_n);
+ if (cfg.vif.driver_cb.valid || !cfg.vif.rst_n)
break;
end
cfg.vif.driver_cb.ready <= 1'b0;
endtask
- // Lower the req line for the given number of cycles
+ // Lower the req line for the given number of cycles. Returns early on reset
virtual task automatic lower_req(int unsigned num_cycles);
cfg.vif.driver_cb.req <= 1'b0;
- repeat (num_cycles) @(cfg.vif.driver_cb);
+ cfg.vif.wait_clks(num_cycles);
cfg.vif.driver_cb.req <= 1'b1;
endtask
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_if.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_if.sv
index a809689..3bf8a62 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_if.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_if.sv
@@ -95,9 +95,28 @@
driver_cb.invalidate <= 1'b0;
endtask
- // A task that waits for num_clks posedges on the clk signal
- task automatic wait_clks(int num_clks);
- repeat (num_clks) @(driver_cb);
+ // A task that waits for num_clks posedges on the clk signal. Returns early on reset if
+ // stop_on_reset is true.
+ task automatic wait_clks(int num_clks, bit stop_on_reset = 1'b1);
+ if (stop_on_reset && !rst_n) return;
+ if (stop_on_reset) begin
+ fork
+ repeat (num_clks) @(driver_cb);
+ @(negedge rst_n);
+ join_any
+ disable fork;
+ end else begin
+ repeat (num_clks) @(driver_cb);
+ end
+ endtask
+
+ // Wait until the valid signal goes high. Returns early on reset
+ task automatic wait_valid();
+ fork
+ @(negedge rst_n);
+ wait (driver_cb.valid);
+ join_any
+ disable fork;
endtask
// Reset all the signals from the core to the cache (the other direction is controlled by the
@@ -122,11 +141,9 @@
// back to a covergroup.
sequence cancelled_valid;
@(posedge clk)
- $rose(valid)
+ (valid & ~ready)
##1
- (valid & ~ready) [*0:$]
- ##1
- (branch, cover_cancelled_valid());
+ (~valid, cover_cancelled_valid());
endsequence : cancelled_valid
cover property (cancelled_valid);
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_monitor.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_monitor.sv
index 3ba90c4..8aab9ac 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_monitor.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/ibex_icache_core_monitor.sv
@@ -21,13 +21,15 @@
endfunction
task run_phase(uvm_phase phase);
- super.run_phase(phase);
-
if (cfg.en_cov) begin
fork
process_cancelled_valid();
join_none
end
+
+ super.run_phase(phase);
+
+ disable fork;
endtask
// collect transactions forever - already forked in dv_base_moditor::run_phase
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_back_line_seq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_back_line_seq.sv
index 8449daa..ab26919 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_back_line_seq.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_back_line_seq.sv
@@ -20,9 +20,9 @@
// "back a bit" from the previous address.
if (!req_phase) begin
min_addr = base_addr;
- max_addr = base_addr + 64;
+ max_addr = top_restricted_addr;
end else begin
- min_addr = last_branch - 16;
+ min_addr = last_branch < 16 ? 0 : last_branch - 16;
max_addr = last_branch;
end
@@ -39,9 +39,9 @@
// of jumping back when the cache isn't ready yet).
num_insns <= 5;
- // The cache should always be enabled and never invalidated
+ // The cache should always be enabled and never invalidated (unless must_invalidate is true)
enable == 1'b1;
- invalidate == 1'b0;
+ invalidate == must_invalidate;
)
finish_item(req);
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_base_seq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_base_seq.sv
index ad9c061..97420b8 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_base_seq.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_core_agent/seq_lib/ibex_icache_core_base_seq.sv
@@ -12,6 +12,10 @@
`uvm_object_new
+ // Non-null if this is an item after the first in a "combo" run, which runs several of these
+ // sequences back-to-back. Must be set before pre_start to have any effect.
+ ibex_icache_core_base_seq prev_sequence = null;
+
// If this is set, any branch target address should be within 64 bytes of base_addr and runs of
// instructions should have a maximum length of 100.
bit constrain_branches = 1'b0;
@@ -24,7 +28,11 @@
// setting.
bit const_enable = 1'b0;
- // If this bit is set, we will never invalidate the cache (useful for hit ratio tracking)
+ // If this bit is set, the next request will invalidate the cache.
+ bit must_invalidate = 1'b0;
+
+ // If this bit is set, we will never invalidate the cache (useful for hit ratio tracking), except
+ // if must_invalidate is set.
bit no_invalidate = 1'b0;
// The expected number of items between each new memory seed when the cache is disabled. A new
@@ -40,14 +48,34 @@
// The expected number of items between enable/disable toggles.
int unsigned gap_between_toggle_enable = 49;
-
// Number of test items (note that a single test item may contain many instruction fetches)
- protected rand int count;
- constraint c_count { count inside {[800:1000]}; }
+ //
+ // The default value is for convenience. This should be constrained by whatever virtual sequence
+ // is using the core sequence.
+ int unsigned num_trans = 1000;
// The base address used when constrain_branches is true.
protected rand bit[31:0] base_addr;
+ // The top of the possible range of addresses used when constrain_branches is true. Set at the
+ // start of body().
+ protected bit [31:0] top_restricted_addr;
+
+ // Distribution for base_addr which adds extra weight to each end of the address space
+ constraint c_base_addr { base_addr dist { [0:15] :/ 1,
+ [16:32'hfffffff0] :/ 2,
+ [32'hfffffff0:32'hffffffff] :/ 1 }; }
+
+ // Make sure that base_addr is even (otherwise you can fail to generate items if you pick a base
+ // addr of 32'hffffffff with constrained addresses enabled: the only address large enough is
+ // 32'hffffffff, but it doesn't have a zero bottom bit).
+ constraint c_base_addr_alignment {
+ // The branch address is always required to be half-word aligned. We don't bother conditioning
+ // this on the type of transaction because branch_addr is forced to be zero in anything but a
+ // branch transaction.
+ !base_addr[0];
+ }
+
// If this is set, the next request should be constrained to have trans_type
// ICacheCoreTransTypeBranch. It's initially 1 because the core must start with a branch to tell
// the cache where to fetch from in the first place.
@@ -70,6 +98,10 @@
// can set initial_enable after constructing the sequence, but before running it.
cache_enabled = initial_enable;
+ // If constrain_branches is true, any branch must land in [base_addr:(base_addr + 64)]. We need
+ // to make sure that this doesn't wrap, though.
+ top_restricted_addr = (base_addr <= (32'hffffffff - 64)) ? base_addr + 64 : 32'hffffffff;
+
run_reqs();
endtask
@@ -88,7 +120,15 @@
// If this is a branch and constrain_branches is true then constrain any branch target.
(constrain_branches && (req.trans_type == ICacheCoreTransTypeBranch)) ->
- req.branch_addr inside {[base_addr:(base_addr + 64)]};
+ req.branch_addr inside {[base_addr:top_restricted_addr]};
+
+ // If this is a branch and constrain_branches is false, we don't constrain the branch target,
+ // but we do weight the bottom and top of the address space a bit higher. This is a weaker
+ // version of the weighting that we place on base_addr.
+ (!constrain_branches && (req.trans_type == ICacheCoreTransTypeBranch)) ->
+ req.branch_addr dist { [0:63] :/ 1,
+ [64:32'hffffffbf] :/ 20,
+ [32'hffffffc0:32'hffffffff] :/ 1 };
// If this is a branch and constrain_branches is true, we can ask for up to 100 instructions
// (independent of insns_since_branch)
@@ -107,8 +147,12 @@
// fetches)
enable dist { cache_enabled :/ gap_between_toggle_enable, ~cache_enabled :/ 1 };
- // If no_invalidate is set, we shouldn't ever touch the invalidate line.
- no_invalidate -> invalidate == 1'b0;
+ // If must_invalidate is set, we have to invalidate with this item.
+ must_invalidate -> invalidate == 1'b1;
+
+ // If no_invalidate is set, we shouldn't ever touch the invalidate line, unless
+ // must_invalidate is set (which will only apply once).
+ (no_invalidate && !must_invalidate) -> invalidate == 1'b0;
// Start an invalidation every 1+gap_between_invalidations items.
invalidate dist { 1'b0 :/ gap_between_invalidations, 1'b1 :/ 1 };
@@ -138,14 +182,17 @@
req.num_insns);
endtask
- // Generate and run count items. Subclasses probably want to configure the parameters above before
+ // Generate and run num_trans items. Subclasses probably want to configure the parameters above before
// running this.
protected task run_reqs();
req = ibex_icache_core_req_item::type_id::create("req");
rsp = ibex_icache_core_rsp_item::type_id::create("rsp");
- repeat (count - 1) begin
+ repeat (num_trans - 1) begin
run_req(req, rsp);
+
+ // Always clear the must_invalidate flag after an item (it's a 1-shot thing)
+ must_invalidate = 1'b0;
end
endtask
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/README.md b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/README.md
new file mode 100644
index 0000000..7b41268
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/README.md
@@ -0,0 +1,3 @@
+# ICache ECC Agent
+
+This very simple agent can be used to inject single-bit and double-bit errors on the interface of a `prim_ram_1p`, used for checking ECC error detection.
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent.core b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent.core
new file mode 100644
index 0000000..ea28be9
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent.core
@@ -0,0 +1,30 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:dv:ibex_icache_ecc_agent:0.1"
+description: "IBEX_ICACHE DV UVM agent"
+filesets:
+ files_dv:
+ depend:
+ - lowrisc:dv:dv_utils
+ - lowrisc:dv:dv_lib
+ - lowrisc:prim:assert
+ files:
+ - ibex_icache_ecc_if.sv
+ - ibex_icache_ecc_protocol_checker.sv
+ - ibex_icache_ecc_agent_pkg.sv
+ - ibex_icache_ecc_item.sv: {is_include_file: true}
+ - ibex_icache_ecc_bus_item.sv: {is_include_file: true}
+ - ibex_icache_ecc_agent_cfg.sv: {is_include_file: true}
+ - ibex_icache_ecc_driver.sv: {is_include_file: true}
+ - ibex_icache_ecc_monitor.sv: {is_include_file: true}
+ - ibex_icache_ecc_agent.sv: {is_include_file: true}
+ - seq_lib/ibex_icache_ecc_base_seq.sv: {is_include_file: true}
+ - seq_lib/ibex_icache_ecc_seq_list.sv: {is_include_file: true}
+ file_type: systemVerilogSource
+
+targets:
+ default:
+ filesets:
+ - files_dv
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent.sv
new file mode 100644
index 0000000..7f490c6
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent.sv
@@ -0,0 +1,23 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_icache_ecc_agent extends dv_base_agent #(
+ .CFG_T (ibex_icache_ecc_agent_cfg),
+ .DRIVER_T (ibex_icache_ecc_driver),
+ .SEQUENCER_T (ibex_icache_ecc_sequencer),
+ .MONITOR_T (ibex_icache_ecc_monitor)
+);
+
+ `uvm_component_utils(ibex_icache_ecc_agent)
+ `uvm_component_new
+
+ function void build_phase(uvm_phase phase);
+ super.build_phase(phase);
+ // get ibex_icache_ecc_if handle
+ if (!uvm_config_db#(virtual ibex_icache_ecc_if)::get(this, "", "vif", cfg.vif)) begin
+ `uvm_fatal(`gfn, "failed to get ibex_icache_ecc_if handle from uvm_config_db")
+ end
+ endfunction
+
+endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent_cfg.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent_cfg.sv
new file mode 100644
index 0000000..4db78a1
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent_cfg.sv
@@ -0,0 +1,18 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_icache_ecc_agent_cfg extends dv_base_agent_cfg;
+
+ // Knobs
+ bit error_prob_pc = 10;
+
+ // interface handle used by driver, monitor & the sequencer, via cfg handle
+ virtual ibex_icache_ecc_if vif;
+
+ `uvm_object_utils_begin(ibex_icache_ecc_agent_cfg)
+ `uvm_object_utils_end
+
+ `uvm_object_new
+
+endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent_pkg.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent_pkg.sv
new file mode 100644
index 0000000..9591f50
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_agent_pkg.sv
@@ -0,0 +1,30 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+package ibex_icache_ecc_agent_pkg;
+ // dep packages
+ import uvm_pkg::*;
+ import dv_utils_pkg::*;
+ import dv_lib_pkg::*;
+
+ // macro includes
+ `include "uvm_macros.svh"
+ `include "dv_macros.svh"
+
+ typedef class ibex_icache_ecc_item;
+ typedef class ibex_icache_ecc_agent_cfg;
+
+ typedef dv_base_sequencer #(.ITEM_T(ibex_icache_ecc_item),
+ .CFG_T (ibex_icache_ecc_agent_cfg)) ibex_icache_ecc_sequencer;
+
+ // package sources
+ `include "ibex_icache_ecc_item.sv"
+ `include "ibex_icache_ecc_bus_item.sv"
+ `include "ibex_icache_ecc_agent_cfg.sv"
+ `include "ibex_icache_ecc_driver.sv"
+ `include "ibex_icache_ecc_monitor.sv"
+ `include "ibex_icache_ecc_agent.sv"
+ `include "ibex_icache_ecc_seq_list.sv"
+
+endpackage: ibex_icache_ecc_agent_pkg
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_bus_item.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_bus_item.sv
new file mode 100644
index 0000000..33e11af
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_bus_item.sv
@@ -0,0 +1,22 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// An item that represents a transaction seen on the interface.
+//
+// Since the interface is a bit weird here (bound in with forced data), we just report the address
+// and data of each read transaction together with its XOR mask.
+
+class ibex_icache_ecc_bus_item extends uvm_sequence_item;
+
+ logic [31:0] addr;
+ logic [127:0] bad_bit_mask;
+ logic [127:0] sram_rdata;
+
+ `uvm_object_utils_begin(ibex_icache_ecc_bus_item)
+ `uvm_field_int (bad_bit_mask, UVM_DEFAULT | UVM_HEX)
+ `uvm_field_int (sram_rdata, UVM_DEFAULT | UVM_HEX)
+ `uvm_object_utils_end
+
+ `uvm_object_new
+endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_driver.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_driver.sv
new file mode 100644
index 0000000..8e813ca
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_driver.sv
@@ -0,0 +1,32 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_icache_ecc_driver
+ extends dv_base_driver #(.ITEM_T (ibex_icache_ecc_item),
+ .CFG_T (ibex_icache_ecc_agent_cfg));
+
+ `uvm_component_utils(ibex_icache_ecc_driver)
+ `uvm_component_new
+
+ virtual task reset_signals();
+ cfg.vif.reset();
+ endtask
+
+ virtual task get_and_drive();
+ forever begin
+ seq_item_port.get_next_item(req);
+ `uvm_info(`gfn, $sformatf("rcvd item:\n%0s", req.sprint()), UVM_HIGH)
+
+ cfg.vif.wait_reads(req.delay);
+ if (req.two_bits) begin
+ cfg.vif.corrupt_read_1(req.bit_pos0);
+ end else begin
+ cfg.vif.corrupt_read_2(req.bit_pos0, req.bit_pos1);
+ end
+
+ seq_item_port.item_done();
+ end
+ endtask
+
+endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_if.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_if.sv
new file mode 100644
index 0000000..60e671c
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_if.sv
@@ -0,0 +1,96 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// An interface that gets bound into a badbit_ram_1p with .*
+
+interface ibex_icache_ecc_if
+ (input logic clk_i,
+ input logic req_i,
+ input logic write_i,
+ input logic [31:0] width,
+ input logic [31:0] addr,
+ input logic [127:0] wdata,
+ input logic [127:0] wmask,
+ input logic [127:0] rdata,
+
+ output logic [127:0] bad_bit_mask);
+
+ // SVA module
+ ibex_icache_ecc_protocol_checker checker_i (.*);
+
+ // The address for the last monitored req transaction
+ logic [31:0] last_addr = 'x;
+
+ bit rst_n = 1'b1;
+
+ // Start a process that will drive the rst_n line low until the next clock, but return
+ // immediately. If rst_n is already low, does nothing.
+ task automatic reset();
+ if (!rst_n) return;
+ rst_n = 1'b0;
+ fork
+ begin
+ @(posedge clk_i);
+ rst_n = 1'b1;
+ end
+ join_none
+ endtask
+
+ // Wait until a cycle with req_i & ~write_i (signalling the start of a read).
+ //
+ // Returns early on reset.
+ task automatic wait_for_read_start();
+ while (rst_n && !(req_i & ~write_i)) @(posedge clk_i);
+ endtask
+
+ // Wait for num_reads complete reads. Ends on the clock posedge where the last read's data is
+ // returned.
+ //
+ // Returns early on reset.
+ task automatic wait_reads(int unsigned num_reads);
+ repeat (num_reads) begin
+ wait_for_read_start();
+ if (!rst_n) break;
+ @(posedge clk_i);
+ end
+ endtask
+
+ // Set a bit to be toggled on the next read
+ task static corrupt_read_1(int unsigned pos);
+ wait_for_read_start();
+ if (!rst_n) return;
+
+ bad_bit_mask = 128'b1 << (pos % width);
+ @(posedge clk_i);
+ bad_bit_mask = 0;
+ endtask
+
+ // Set two bits to be toggled on the next read
+ task static corrupt_read_2(int unsigned pos0, int unsigned pos1);
+ wait_for_read_start();
+ if (!rst_n) return;
+
+ bad_bit_mask = (128'b1 << (pos0 % width)) | (128'b1 << (pos1 % width));
+ @(posedge clk_i);
+ bad_bit_mask = 0;
+ endtask
+
+ // Wait for a read, setting last_addr accordingly.
+ //
+ // This can be called re-entrantly, despite writing last_addr (it will just write the same value
+ // more than once).
+ //
+ // Returns early on reset.
+ task automatic wait_read();
+ wait_for_read_start();
+ if (!rst_n) return;
+ last_addr = addr;
+ @(posedge clk_i);
+ endtask
+
+ initial begin
+ bad_bit_mask = 0;
+ end
+
+endinterface
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_item.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_item.sv
new file mode 100644
index 0000000..34944c1
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_item.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
+
+// A sequence item that represents a bit twiddle.
+//
+// The item will wait <delay> other reads before taking effect. When it does take effect, it toggles
+// 1 or 2 bits in the read value. If <two_bits> is true, the bits at positions <bit_pos0> and
+// <bit_pos1> will be toggled. Otherwise, just the bit at <bit_pos0> will be.
+//
+// <bit_pos0> and <bit_pos1> are interpreted modulo the interface width in the driver, so don't need
+// constraining.
+
+class ibex_icache_ecc_item extends uvm_sequence_item;
+
+ rand bit two_bits;
+ rand int unsigned bit_pos0;
+ rand int unsigned bit_pos1;
+ rand int unsigned delay;
+
+ `uvm_object_utils_begin(ibex_icache_ecc_item)
+ `uvm_field_int (two_bits, UVM_DEFAULT)
+ `uvm_field_int (bit_pos0, UVM_DEFAULT)
+ `uvm_field_int (bit_pos1, UVM_DEFAULT)
+ `uvm_field_int (delay, UVM_DEFAULT)
+ `uvm_object_utils_end
+
+ `uvm_object_new
+endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_monitor.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_monitor.sv
new file mode 100644
index 0000000..f2b1054
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_monitor.sv
@@ -0,0 +1,35 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_icache_ecc_monitor extends dv_base_monitor #(
+ .ITEM_T (ibex_icache_ecc_bus_item),
+ .CFG_T (ibex_icache_ecc_agent_cfg)
+ );
+ `uvm_component_utils(ibex_icache_ecc_monitor)
+
+ // the base class provides the following handles for use:
+ // ibex_icache_ecc_agent_cfg: cfg
+ // ibex_icache_ecc_agent_cov: cov
+ // uvm_analysis_port #(ibex_icache_ecc_bus_item): analysis_port
+
+ `uvm_component_new
+
+ // collect transactions forever - already forked in dv_base_moditor::run_phase
+ virtual protected task collect_trans(uvm_phase phase);
+ ibex_icache_ecc_bus_item trans;
+ forever begin
+ cfg.vif.wait_read();
+ // If this isn't a reset pulse, we have a read transaction. Report it.
+ if (!cfg.vif.rst_n) begin
+ trans = ibex_icache_ecc_bus_item::type_id::create("trans");
+ trans.addr = cfg.vif.last_addr;
+ trans.bad_bit_mask = cfg.vif.bad_bit_mask;
+ trans.sram_rdata = cfg.vif.rdata;
+ analysis_port.write(trans);
+ end
+ @(posedge cfg.vif.clk_i);
+ end
+ endtask
+
+endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_protocol_checker.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_protocol_checker.sv
new file mode 100644
index 0000000..9dff146
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/ibex_icache_ecc_protocol_checker.sv
@@ -0,0 +1,37 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// An interface that contains SV assertions to check that the icache <-> SRAM interface is being
+// driven correctly.
+//
+// This should be instantiated inside ibex_icache_ecc_if. The input names are the same as the
+// signals in the interface (no _i suffix), so that this can be instantiated with .*
+
+`include "prim_assert.sv"
+
+interface ibex_icache_ecc_protocol_checker
+ (input logic clk_i,
+ input logic req_i,
+ input logic write_i,
+ input logic [31:0] width,
+ input logic [31:0] addr,
+ input logic [127:0] wdata,
+ input logic [127:0] wmask,
+ input logic [127:0] rdata);
+
+ // The req line should never be unknown. Note that we have no reset signal here, so we assert this
+ // is true at all times (fortunately, it seems that the DUT holds req low when in reset).
+ `ASSERT_KNOWN(ReqKnown, req_i, clk_i, 0)
+
+ // If there is a request, the write signal should be known
+ `ASSERT_KNOWN_IF(WriteKnown, write_i, req_i, clk_i, 0)
+
+ // If there is a request with write_i high, the address and write mask should be known, and so
+ // should any data to be written. We don't require the address to be known for reads: reading
+ // rubbish is fine, so long as we ignore it later.
+ `ASSERT_KNOWN_IF(AddrKnown, addr, req_i & write_i, clk_i, 0)
+ `ASSERT_KNOWN_IF(WMaskKnown, wmask, req_i & write_i, clk_i, 0)
+ `ASSERT_KNOWN_IF(WDataKnown, wdata & wmask, req_i & write_i, clk_i, 0)
+
+endinterface
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_base_seq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_base_seq.sv
new file mode 100644
index 0000000..e37c94b
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_base_seq.sv
@@ -0,0 +1,25 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class ibex_icache_ecc_base_seq
+ extends dv_base_seq #(.REQ (ibex_icache_ecc_item),
+ .CFG_T (ibex_icache_ecc_agent_cfg),
+ .SEQUENCER_T (ibex_icache_ecc_sequencer));
+ `uvm_object_utils(ibex_icache_ecc_base_seq)
+
+ `uvm_object_new
+
+ virtual task body();
+ forever begin
+ req = ibex_icache_ecc_item::type_id::create("req");
+ start_item(req);
+ `DV_CHECK_RANDOMIZE_WITH_FATAL(req,
+ req.delay dist {0 :/ 1,
+ [1:20] :/ 1,
+ [21:50] :/ 1};)
+ finish_item(req);
+ end
+ endtask
+
+endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_seq_list.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_seq_list.sv
new file mode 100644
index 0000000..ccc8b96
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_ecc_agent/seq_lib/ibex_icache_ecc_seq_list.sv
@@ -0,0 +1,5 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "ibex_icache_ecc_base_seq.sv"
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_driver.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_driver.sv
index ca5546b..10bca4a 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_driver.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_driver.sv
@@ -30,7 +30,15 @@
endfunction
virtual task reset_signals();
+ ibex_icache_mem_resp_item resp;
+ bit [32:0] req;
+
cfg.vif.reset();
+
+ // Flush mailboxes of pending requests and responses
+ while (req_queue.try_get(req)) ;
+ while (rdata_queue.try_get(resp)) ;
+
endtask
virtual task get_and_drive();
@@ -40,6 +48,7 @@
take_requests();
drive_pmp();
drive_responses();
+ drive_resets();
join
endtask
@@ -93,7 +102,11 @@
forever begin
rdata_queue.get(item);
+ if (!cfg.vif.rst_n) continue;
+
cfg.vif.wait_clks(item.delay);
+ if (!cfg.vif.rst_n) continue;
+
cfg.vif.send_response(item.err, item.rdata);
end
endtask
@@ -117,6 +130,8 @@
req_queue.get(data);
{err, address} = data;
+ if (!cfg.vif.rst_n) continue;
+
// If err is false, this is a request which shouldn't trigger a PMP error.
if (!err) continue;
@@ -131,8 +146,8 @@
req_queue.peek(data);
begin
cfg.vif.pmp_err <= 1'b1;
- // Wait for an address change or req to de-assert
- @(negedge cfg.vif.req or cfg.vif.addr);
+ // Wait for a reset, an address change or req to de-assert
+ @(negedge cfg.vif.rst_n or negedge cfg.vif.req or cfg.vif.addr);
end
join_any
disable fork;
@@ -140,4 +155,9 @@
end
endtask
+ // Watch for resets and call reset_signals as needed
+ task automatic drive_resets();
+ forever @(negedge cfg.vif.rst_n) reset_signals();
+ endtask
+
endclass
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_if.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_if.sv
index f3ff1ef..ff2e1d1 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_if.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_if.sv
@@ -55,9 +55,14 @@
driver_cb.gnt <= 1'b0;
endtask
- // Wait for num_clks posedges on the clk signal
+ // Wait for num_clks posedges on the clk signal. Returns early on a reset.
task automatic wait_clks(int num_clks);
- repeat (num_clks) @(driver_cb);
+ if (!rst_n) return;
+ fork
+ repeat (num_clks) @(driver_cb);
+ @(negedge rst_n);
+ join_any
+ disable fork;
endtask
// Drive a response with the given rdata and possible error signals for a single cycle
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_model.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_model.sv
index 6d163e7..8196d5d 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_model.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/ibex_icache_mem_model.sv
@@ -29,29 +29,24 @@
// If set, disable memory errors
protected bit no_mem_errs;
- // The power of two by which to divide the address space to get the error range: see is_error for
- // details.
- protected int unsigned error_shift;
-
function new(string name="",
bit disable_pmp_errs=0,
- bit disable_mem_errs=0,
- int unsigned err_shift=3);
+ bit disable_mem_errs=0);
no_pmp_errs = disable_pmp_errs;
no_mem_errs = disable_mem_errs;
- error_shift = err_shift;
endfunction
`uvm_object_utils_begin(ibex_icache_mem_model)
`uvm_field_int (no_pmp_errs, UVM_DEFAULT)
`uvm_field_int (no_mem_errs, UVM_DEFAULT)
- `uvm_field_int (error_shift, UVM_DEFAULT)
`uvm_object_utils_end
// Return true if reading BusWidth bits from address intersects with the error range given by the
// current seed. The error range has a length of (1/2^error_shift) times the size of the address
// space.
- protected function automatic logic is_error(bit [31:0] seed, logic [31:0] address);
+ protected function automatic logic
+ is_error(bit [31:0] seed, logic [31:0] address, int unsigned error_shift);
+
logic [31:0] rng_lo, rng_hi, rng_w0, rng_w1;
rng_lo = seed ^ 32'hdeadbeef;
rng_w0 = 32'd1 << (32 - error_shift);
@@ -65,18 +60,18 @@
endfunction
// Return true if reading BusWidth bits from address should give a PMP error
- function automatic logic is_pmp_error(bit [31:0] seed, logic [31:0] address);
- return (! no_pmp_errs) && is_error(seed, address ^ 32'h12344321);
+ function automatic logic is_pmp_error(bit [31:0] seed, logic [31:0] addr, int unsigned err_shift);
+ return (! no_pmp_errs) && is_error(seed, addr ^ 32'h12344321, err_shift);
endfunction
// Return true if reading BusWidth bits from address should give a memory error
- function automatic logic is_mem_error(bit [31:0] seed, logic [31:0] address);
- return (! no_mem_errs) && is_error(seed, address ^ 32'hf00dbeef);
+ function automatic logic is_mem_error(bit [31:0] seed, logic [31:0] addr, int unsigned err_shift);
+ return (! no_mem_errs) && is_error(seed, addr ^ 32'hf00dbeef, err_shift);
endfunction
// Return true if reading BusWidth bits from address should give some sort of error
- function automatic logic is_either_error(bit [31:0] seed, logic [31:0] address);
- return is_pmp_error(seed, address) || is_mem_error(seed, address);
+ function automatic logic is_either_error(bit [31:0] seed, logic [31:0] addr, int unsigned err_shift);
+ return is_pmp_error(seed, addr, err_shift) || is_mem_error(seed, addr, err_shift);
endfunction
// Return BusWidth bits of data from reading at address.
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/seq_lib/ibex_icache_mem_resp_seq.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/seq_lib/ibex_icache_mem_resp_seq.sv
index ad4a3a6..5e60cbf 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/seq_lib/ibex_icache_mem_resp_seq.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_mem_agent/seq_lib/ibex_icache_mem_resp_seq.sv
@@ -6,7 +6,9 @@
class ibex_icache_mem_resp_seq extends ibex_icache_mem_base_seq;
- // Knobs
+ // Non-null if this is an item after the first in a "combo" run, which runs several of these
+ // sequences back-to-back. Must be set before pre_start to have any effect.
+ ibex_icache_mem_resp_seq prev_sequence = null;
protected ibex_icache_mem_model #(.BusWidth (32)) mem_model;
@@ -24,30 +26,44 @@
// To avoid this problem, we keep a queue of pending addresses along with their corresponding
// seeds. When a grant message comes in, we know that we can look up the correct seed there,
// discarding results until we find it.
- protected bit [63:0] pending_grants[$];
- protected bit [31:0] cur_seed = 0;
+ bit [63:0] pending_grants[$];
+ bit [31:0] cur_seed = 0;
`uvm_object_utils(ibex_icache_mem_resp_seq)
`uvm_object_new
task pre_start();
super.pre_start();
- mem_model = new("mem_model", cfg.disable_pmp_errs, cfg.disable_mem_errs, cfg.mem_err_shift);
+ mem_model = new("mem_model", cfg.disable_pmp_errs, cfg.disable_mem_errs);
+
+ // Take any pending grants and seed from a previous sequence
+ if (prev_sequence) begin
+ pending_grants = prev_sequence.pending_grants;
+ cur_seed = prev_sequence.cur_seed;
+ end
endtask
task body();
ibex_icache_mem_req_item req_item = new("req_item");
+ ibex_icache_mem_req_item req_item2 = new("req_item2");
ibex_icache_mem_resp_item resp_item = new("resp_item");
forever begin
- // Wait for a transaction request.
- p_sequencer.request_fifo.get(req_item);
+ // Wait for a transaction request. We use peek, handle the request, and then get (and drop)
+ // the item. This means that if our sequence is killed in the middle of handling it, the item
+ // will still be passed from the monitor to any later sequence.
+ p_sequencer.request_fifo.get_peek_export.peek(req_item);
if (!req_item.is_grant) begin
take_req(resp_item, req_item);
end else begin
take_gnt(resp_item, req_item);
end
+
+ // Get and drop the request item now that we've dealt with it. As a sanity check, make sure
+ // that the two items match.
+ p_sequencer.request_fifo.get_peek_export.get(req_item2);
+ `DV_CHECK_EQ_FATAL(req_item, req_item2)
end
endtask
@@ -75,7 +91,7 @@
resp_item.is_grant = 1'b0;
resp_item.address = req_item.address;
resp_item.rdata = 'X;
- resp_item.err = mem_model.is_pmp_error(cur_seed, req_item.address);
+ resp_item.err = mem_model.is_pmp_error(cur_seed, req_item.address, cfg.mem_err_shift);
start_item(resp_item);
`DV_CHECK_RANDOMIZE_FATAL(resp_item)
@@ -116,7 +132,7 @@
// Using the seed that we saw for the request, check the memory model for a (non-PMP) error
// at this address. On success, look up the memory data too.
resp_item.is_grant = 1'b1;
- resp_item.err = mem_model.is_mem_error(gnt_seed, req_item.address);
+ resp_item.err = mem_model.is_mem_error(gnt_seed, req_item.address, cfg.mem_err_shift);
resp_item.address = req_item.address;
resp_item.rdata = resp_item.err ? 'X : mem_model.read_data(gnt_seed, req_item.address);
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_sim.core b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_sim.core
index 1992b80..403f8d1 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_sim.core
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_sim.core
@@ -18,8 +18,17 @@
targets:
sim:
+ parameters:
+ - PRIM_DEFAULT_IMPL=prim_pkg::ImplBadbit
filesets:
- files_rtl
- files_dv
toplevel: tb
default_tool: vcs
+
+parameters:
+ PRIM_DEFAULT_IMPL:
+ datatype: str
+ paramtype: vlogdefine
+ description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
+ default: prim_pkg::ImplBadbit
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_sim_cfg.hjson b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_sim_cfg.hjson
index 19c5995..17742df 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_sim_cfg.hjson
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/ibex_icache_sim_cfg.hjson
@@ -20,10 +20,26 @@
// Testplan hjson file.
testplan: "{proj_root}/dv/uvm/icache/data/ibex_icache_testplan.hjson"
-
// Import additional common sim cfg files.
- import_cfgs: [// Project wide common sim cfg file
- "{proj_root}/dv/uvm/data/common_sim_cfg.hjson"]
+ import_cfgs: [
+ // Project wide common sim cfg file
+ "{proj_root}/dv/uvm/data/common_sim_cfg.hjson"
+ ]
+
+ build_modes: [
+ {
+ name: default
+ en_build_modes: ["{tool}_icache_ecc"]
+ }
+ {
+ name: vcs_icache_ecc
+ build_opts: ["-gv tb.ICacheECC=1"]
+ }
+ {
+ name: riviera_icache_ecc
+ run_opts: ["-gICacheECC=1"]
+ }
+ ]
// Default iterations for all tests - each test entry can override this.
reseed: 50
@@ -42,7 +58,7 @@
tests: [
{
name: ibex_icache_sanity
- uvm_test_seq: ibex_icache_sanity_vseq
+ uvm_test_seq: ibex_icache_base_vseq
}
{
@@ -74,7 +90,21 @@
{
name: ibex_icache_many_errors
uvm_test_seq: ibex_icache_many_errors_vseq
- uvm_test: ibex_icache_many_errors_test
+ }
+
+ {
+ name: ibex_icache_ecc
+ uvm_test_seq: ibex_icache_ecc_vseq
+ }
+
+ {
+ name: ibex_icache_stress_all
+ uvm_test_seq: ibex_icache_combo_vseq
+ }
+
+ {
+ name: ibex_icache_stress_all_with_reset
+ uvm_test_seq: ibex_icache_reset_vseq
}
]
@@ -87,8 +117,10 @@
"ibex_icache_caching",
"ibex_icache_invalidation",
"ibex_icache_back_line",
- "ibex_icache_many_errors"]
+ "ibex_icache_many_errors",
+ "ibex_icache_ecc",
+ "ibex_icache_stress_all",
+ "ibex_icache_stress_all_with_reset"]
}
]
}
-
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/README.md b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/README.md
new file mode 100644
index 0000000..22aebb5
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/README.md
@@ -0,0 +1,11 @@
+Badbit RAM
+==========
+
+This is an SRAM wrapper that allows a testbench to force bit errors onthe read interface.
+
+This works as a dummy technology library.
+Instantiate it by adding setting `PRIM_DEFAULT_IMPL` to prim_pkg::ImplBadbit (see the README.md in the prim directory for details).
+To use it, bind a module or interface into an instance of `prim_badbit_ram_1p` and force the value of `bad_bit_mask`, which is XOR'd with rdata.
+
+To make this easier to use, we don't vary the width of `bad_bit_mask` with the `Width` parameter: it's a constant 128.
+This means that the bound interface doesn't need to be parameterised.
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.core b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.core
new file mode 100644
index 0000000..df81ec5
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.core
@@ -0,0 +1,20 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+name: "lowrisc:prim_badbit:ram_1p"
+description: "Single-port RAM which allows a bound interface to inject errors"
+filesets:
+ files_rtl:
+ depend:
+ - lowrisc:prim_generic:ram_1p
+ - lowrisc:prim:assert
+ files:
+ - prim_badbit_ram_1p.sv
+ file_type: systemVerilogSource
+
+targets:
+ default:
+ filesets:
+ - files_rtl
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.sv
new file mode 100644
index 0000000..f7201f0
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/prim_badbit/prim_badbit_ram_1p.sv
@@ -0,0 +1,83 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// Single-port SRAM model which allows a test to corrupt read responses from the underlying memory.
+//
+// To use this, instantiate it then bind in a module or interface that has bad_bit_mask as an
+// output. A nonzero bit in bad_bit_mask will cause the corresponding bit to be flipped in the
+// response.
+
+`include "prim_assert.sv"
+
+module prim_badbit_ram_1p #(
+ parameter int Width = 32, // bit
+ parameter int Depth = 128,
+ parameter int DataBitsPerMask = 1, // Number of data bits per bit of write mask
+ parameter MemInitFile = "", // VMEM file to initialize the memory with
+
+ localparam int Aw = $clog2(Depth) // derived parameter
+) (
+ input logic clk_i,
+
+ input logic req_i,
+ input logic write_i,
+ input logic [Aw-1:0] addr_i,
+ input logic [Width-1:0] wdata_i,
+ input logic [Width-1:0] wmask_i,
+ output logic [Width-1:0] rdata_o // Read data. Data is returned one cycle after req_i is high.
+);
+
+ logic [Width-1:0] sram_rdata;
+
+ prim_generic_ram_1p #(
+ .Width (Width),
+ .Depth (Depth),
+ .DataBitsPerMask (DataBitsPerMask),
+ .MemInitFile (MemInitFile)
+ ) u_mem (
+ .clk_i (clk_i),
+
+ .req_i (req_i),
+ .write_i (write_i),
+ .addr_i (addr_i),
+ .wdata_i (wdata_i),
+ .wmask_i (wmask_i),
+ .rdata_o (sram_rdata)
+ );
+
+ // This module doesn't work with Verilator (because of the wired-or). Because we define the
+ // "badbit" ram as a technology library, it gets picked up and parsed by any tool using the Ibex
+ // repo. Rather than telling Verilator to ignore the whole lot (which causes NOTFOUNDMODULE
+ // warnings), we just hide the actual guts.
+`ifdef VERILATOR
+ assign rdata_o = sram_rdata;
+`else
+ // Making bad_bit_mask a constant size makes this easier to use (because you don't need to faff
+ // around with parameterised interfaces in your UVM database). Check that rdata_o is actually
+ // controllable. Similarly, we make the address a constant width: make sure that's large enough.
+ `ASSERT_INIT(WidthSmallEnough, Width <= 128)
+ `ASSERT_INIT(AddrSmallEnough, Aw <= 32)
+
+ // Make the Width parameter easily accessible to bound-in modules.
+ logic [31:0] width;
+ assign width = Width;
+
+ // Similarly, extend addr, wdata, wmask and sram_rdata (the un-fiddled value)
+ logic [31:0] addr;
+ logic [127:0] wdata, wmask, rdata;
+ assign addr = {{32-Aw{1'b0}}, addr_i};
+ assign wdata = {{128-Width{1'b0}}, wdata_i};
+ assign wmask = {{128-Width{1'b0}}, wmask_i};
+ assign rdata = {{128-Width{1'b0}}, sram_rdata};
+
+ // To inject errors, bind in an interface with bad_bit_mask as an output and assign one of the
+ // bits in bad_bit_mask[Width-1:0] to one. The wired-OR together with an assignment to zero means
+ // this acts like a weak pull-down.
+ wor [127:0] bad_bit_mask;
+ assign bad_bit_mask = 128'b0;
+
+ assign rdata_o = sram_rdata ^ bad_bit_mask;
+`endif // VERILATOR
+
+endmodule
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tb/tb.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tb/tb.sv
index 60a8d30..c4925c4 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tb/tb.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tb/tb.sv
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
-module tb;
+module tb #(parameter bit ICacheECC = 1'b0);
// dep packages
import uvm_pkg::*;
import dv_utils_pkg::*;
@@ -22,7 +22,9 @@
ibex_icache_mem_if mem_if (.clk(clk), .rst_n(rst_n));
// dut
- ibex_icache dut (
+ ibex_icache #(
+ .ICacheECC (ICacheECC)
+ ) dut (
.clk_i (clk),
.rst_ni (rst_n),
@@ -51,12 +53,45 @@
.instr_rvalid_i (mem_if.rvalid)
);
+ // If the ICacheECC parameter is set in the DUT, generate another interface for each tag ram and
+ // each data ram, binding them into the RAMs themselves. ECC tests can use these to insert errors
+ // into memory lookups.
+ generate if (dut.ICacheECC) begin : gen_ecc
+ for (genvar w = 0; w < dut.NumWays; w++) begin : gen_ecc_ifs
+ bind dut.gen_rams[w].tag_bank.gen_badbit.u_impl_badbit ibex_icache_ecc_if tag_bank_if (.*);
+ bind dut.gen_rams[w].data_bank.gen_badbit.u_impl_badbit ibex_icache_ecc_if data_bank_if (.*);
+
+ initial begin
+ uvm_config_db#(virtual ibex_icache_ecc_if)::
+ set(null,
+ $sformatf("*.env.ecc_tag_agents[%0d]*", w),
+ "vif",
+ dut.gen_rams[w].tag_bank.gen_badbit.u_impl_badbit.tag_bank_if);
+
+ uvm_config_db#(virtual ibex_icache_ecc_if)::
+ set(null,
+ $sformatf("*.env.ecc_data_agents[%0d]*", w),
+ "vif",
+ dut.gen_rams[w].data_bank.gen_badbit.u_impl_badbit.data_bank_if);
+ end
+ end
+ end
+ endgenerate
+
initial begin
// drive clk and rst_n from clk_if
clk_rst_if.set_active();
+
+ // Store virtual interfaces into the UVM config database. ECC interfaces are done separately
+ // above because otherwise you have to repeat the (verbose) generate loop.
uvm_config_db#(virtual clk_rst_if)::set(null, "*.env", "clk_rst_vif", clk_rst_if);
uvm_config_db#(virtual ibex_icache_core_if)::set(null, "*.env.core_agent*", "vif", core_if);
uvm_config_db#(virtual ibex_icache_mem_if)::set(null, "*.env.mem_agent*", "vif", mem_if);
+
+ // Record the number of (ECC) ways in the config database. The top-level environment's config
+ // will use this to decide how many agents to create.
+ uvm_config_db#(int unsigned)::set(null, "*", "num_ecc_ways", dut.ICacheECC ? dut.NumWays : 0);
+
$timeformat(-12, 0, " ps", 12);
run_test();
end
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_base_test.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_base_test.sv
index 7939614..ecce213 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_base_test.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_base_test.sv
@@ -15,8 +15,19 @@
// ibex_icache_env: env
virtual function void build_phase(uvm_phase phase);
+ int unsigned num_ecc_ways;
+ if (!uvm_config_db#(int unsigned)::get(this, "", "num_ecc_ways", num_ecc_ways)) begin
+ `uvm_fatal(`gfn, "failed to get num_ecc_ways from uvm_config_db")
+ end
+
super.build_phase(phase);
+
cfg.has_ral = 1'b0;
+
+ // Create config objects for each of the ECC agents. We can't do that in the config object
+ // itself (because that's not a component, so doesn't have access to the uvm_config_db).
+ cfg.create_ecc_agent_cfgs(num_ecc_ways);
+
endfunction
// the base class also looks up UVM_TEST_SEQ plusarg to create and run that seq in
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_many_errors_test.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_many_errors_test.sv
deleted file mode 100644
index 1c3bdc6..0000000
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_many_errors_test.sv
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-class ibex_icache_many_errors_test extends ibex_icache_base_test;
-
- `uvm_component_utils(ibex_icache_many_errors_test)
- `uvm_component_new
-
- virtual function void build_phase(uvm_phase phase);
- super.build_phase(phase);
-
- // Increase the error rate (to roughly 50%)
- cfg.mem_agent_cfg.mem_err_shift = 1;
- endfunction
-
-endclass : ibex_icache_many_errors_test
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_test.core b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_test.core
index ec7a617..b580205 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_test.core
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_test.core
@@ -12,7 +12,6 @@
- ibex_icache_test_pkg.sv
- ibex_icache_base_test.sv: {is_include_file: true}
- ibex_icache_oldval_test.sv: {is_include_file: true}
- - ibex_icache_many_errors_test.sv: {is_include_file: true}
file_type: systemVerilogSource
targets:
diff --git a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_test_pkg.sv b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_test_pkg.sv
index f76d0b7..4d62127 100644
--- a/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_test_pkg.sv
+++ b/hw/vendor/lowrisc_ibex/dv/uvm/icache/dv/tests/ibex_icache_test_pkg.sv
@@ -19,6 +19,5 @@
// package sources
`include "ibex_icache_base_test.sv"
`include "ibex_icache_oldval_test.sv"
- `include "ibex_icache_many_errors_test.sv"
endpackage
diff --git a/hw/vendor/lowrisc_ibex/ibex_configs.yaml b/hw/vendor/lowrisc_ibex/ibex_configs.yaml
index 9d7f64d..6929140 100644
--- a/hw/vendor/lowrisc_ibex/ibex_configs.yaml
+++ b/hw/vendor/lowrisc_ibex/ibex_configs.yaml
@@ -24,7 +24,19 @@
# Three-stage pipeline with additional branch traget ALU and 1 cycle multiplier
# (2 cycles for mulh) so mul does not stall (mulh stall 1 cycles). This is the
-# maximum performance configuration. PMP is enabled with 16 regions.
+# maximum performance configuration.
+experimental-maxperf:
+ RV32E : 0
+ RV32M : 1
+ RV32B : 0
+ BranchTargetALU : 1
+ WritebackStage : 1
+ MultiplierImplementation : "single-cycle"
+ PMPEnable : 0
+ PMPGranularity : 0
+ PMPNumRegions : 4
+
+# experimental-maxperf config above plus PMP enabled with 16 regions.
experimental-maxperf-pmp:
RV32E : 0
RV32M : 1
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_alu.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_alu.sv
index de0e59f..0f59328 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_alu.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_alu.sv
@@ -591,9 +591,9 @@
`define _N(stg) (16 >> stg)
// bext / bdep control bit generation
- for (genvar stg=0; stg<5; stg++) begin
+ for (genvar stg=0; stg<5; stg++) begin : gen_stage
// number of segs: 2** stg
- for (genvar seg=0; seg<2**stg; seg++) begin
+ for (genvar seg=0; seg<2**stg; seg++) begin : gen_segment
assign lrotc_stage[stg][2*`_N(stg)*(seg+1)-1 : 2*`_N(stg)*seg] =
{{`_N(stg){1'b0}},{`_N(stg){1'b1}}} <<
@@ -611,7 +611,7 @@
end
`undef _N
- for (genvar stg=0; stg<5; stg++) begin
+ for (genvar stg=0; stg<5; stg++) begin : gen_zbe_mask
assign butterfly_zbe_mask_not[stg] =
~(butterfly_zbe_mask_l[stg] | butterfly_zbe_mask_r[stg]);
end
@@ -708,17 +708,17 @@
// Shuffle / Unshuffle //
/////////////////////////
- localparam logic [31:0] SHUFFLE_MASK_L [0:3] =
- '{32'h00ff_0000, 32'h0f00_0f00, 32'h3030_3030, 32'h4444_4444};
- localparam logic [31:0] SHUFFLE_MASK_R [0:3] =
- '{32'h0000_ff00, 32'h00f0_00f0, 32'h0c0c_0c0c, 32'h2222_2222};
+ localparam logic [31:0] SHUFFLE_MASK_L [4] =
+ '{32'h4444_4444, 32'h3030_3030, 32'h0f00_0f00, 32'h00ff_0000};
+ localparam logic [31:0] SHUFFLE_MASK_R [4] =
+ '{32'h2222_2222, 32'h0c0c_0c0c, 32'h00f0_00f0, 32'h0000_ff00};
- localparam logic [31:0] FLIP_MASK_L [0:3] =
- '{32'h2200_1100, 32'h0044_0000, 32'h4411_0000, 32'h1100_0000};
- localparam logic [31:0] FLIP_MASK_R [0:3] =
- '{32'h0088_0044, 32'h0000_2200, 32'h0000_8822, 32'h0000_0088};
+ localparam logic [31:0] FLIP_MASK_L [4] =
+ '{32'h1100_0000, 32'h4411_0000, 32'h0044_0000, 32'h2200_1100};
+ localparam logic [31:0] FLIP_MASK_R [4] =
+ '{32'h0000_0088, 32'h0000_8822, 32'h0000_2200, 32'h0088_0044};
- logic [31:0] SHUFFLE_MASK_NOT [0:3];
+ logic [31:0] SHUFFLE_MASK_NOT [4];
for(genvar i = 0; i < 4; i++) begin : gen_shuffle_mask_not
assign SHUFFLE_MASK_NOT[i] = ~(SHUFFLE_MASK_L[i] | SHUFFLE_MASK_R[i]);
end
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv
index ccb6bdc..2bbc373 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_controller.sv
@@ -15,7 +15,6 @@
input logic clk_i,
input logic rst_ni,
- input logic fetch_enable_i, // start decoding
output logic ctrl_busy_o, // core is busy processing instrs
// decoder related signals
@@ -396,14 +395,11 @@
unique case (ctrl_fsm_cs)
RESET: begin
- // just wait for fetch_enable
instr_req_o = 1'b0;
pc_mux_o = PC_BOOT;
pc_set_o = 1'b1;
pc_set_spec_o = 1'b1;
- if (fetch_enable_i) begin
- ctrl_fsm_ns = BOOT_SET;
- end
+ ctrl_fsm_ns = BOOT_SET;
end
BOOT_SET: begin
@@ -719,6 +715,7 @@
exc_cause_o = EXC_CAUSE_LOAD_ACCESS_FAULT;
csr_mtval_o = lsu_addr_last_i;
end
+ default: ;
endcase
end else begin
// special instructions and pipeline flushes
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv
index 2303813..6fd1b40 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_core.sv
@@ -353,8 +353,17 @@
core_busy_q <= core_busy_d;
end
end
+ // capture fetch_enable_i in fetch_enable_q, once for ever
+ logic fetch_enable_q;
+ always_ff @(posedge clk_i or negedge rst_ni) begin
+ if (!rst_ni) begin
+ fetch_enable_q <= 1'b0;
+ end else if (fetch_enable_i) begin
+ fetch_enable_q <= 1'b1;
+ end
+ end
- assign clock_en = core_busy_q | debug_req_i | irq_pending | irq_nm_i;
+ assign clock_en = fetch_enable_q & (core_busy_q | debug_req_i | irq_pending | irq_nm_i);
assign core_sleep_o = ~clock_en;
// main clock gate of the core
@@ -460,7 +469,6 @@
.rst_ni ( rst_ni ),
// Processor Enable
- .fetch_enable_i ( fetch_enable_i ),
.ctrl_busy_o ( ctrl_busy ),
.illegal_insn_o ( illegal_insn_id ),
@@ -705,7 +713,7 @@
ibex_wb_stage #(
.WritebackStage ( WritebackStage )
) wb_stage_i (
- .clk_i ( clk_i ),
+ .clk_i ( clk ),
.rst_ni ( rst_ni ),
.en_wb_i ( en_wb ),
.instr_type_wb_i ( instr_type_wb ),
@@ -740,7 +748,7 @@
.DataWidth (32),
.DummyInstructions (DummyInstructions)
) register_file_i (
- .clk_i ( clk_i ),
+ .clk_i ( clk ),
.rst_ni ( rst_ni ),
.test_en_i ( test_en_i ),
@@ -770,7 +778,7 @@
assign outstanding_load_id = id_stage_i.instr_executing & id_stage_i.lsu_req_dec & ~id_stage_i.lsu_we;
assign outstanding_store_id = id_stage_i.instr_executing & id_stage_i.lsu_req_dec & id_stage_i.lsu_we;
- if (WritebackStage) begin
+ if (WritebackStage) begin : gen_wb_stage
// When the writeback stage is present a load/store could be in ID or WB. A Load/store in ID can
// see a response before it moves to WB when it is unaligned otherwise we should only see
// a response when load/store is in WB.
@@ -782,7 +790,7 @@
// When writing back the result of a load, the load must have made it to writeback
`ASSERT(NoMemRFWriteWithoutPendingLoad, rf_we_lsu |-> outstanding_load_wb, clk_i, !rst_ni)
- end else begin
+ end else begin : gen_no_wb_stage
// Without writeback stage only look into whether load or store is in ID to determine if
// a response is expected.
assign outstanding_load_resp = outstanding_load_id;
@@ -967,33 +975,33 @@
// second stage. RVFI outputs are all straight from flops. So 2 stage pipeline requires a single
// set of flops (instr_info => RVFI_out), 3 stage pipeline requires two sets (instr_info => wb
// => RVFI_out)
- localparam RVFI_STAGES = WritebackStage ? 2 : 1;
+ localparam int RVFI_STAGES = WritebackStage ? 2 : 1;
- logic rvfi_stage_valid [RVFI_STAGES-1:0];
- logic [63:0] rvfi_stage_order [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_insn [RVFI_STAGES-1:0];
- logic rvfi_stage_trap [RVFI_STAGES-1:0];
- logic rvfi_stage_halt [RVFI_STAGES-1:0];
- logic rvfi_stage_intr [RVFI_STAGES-1:0];
- logic [ 1:0] rvfi_stage_mode [RVFI_STAGES-1:0];
- logic [ 1:0] rvfi_stage_ixl [RVFI_STAGES-1:0];
- logic [ 4:0] rvfi_stage_rs1_addr [RVFI_STAGES-1:0];
- logic [ 4:0] rvfi_stage_rs2_addr [RVFI_STAGES-1:0];
- logic [ 4:0] rvfi_stage_rs3_addr [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_rs1_rdata [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_rs2_rdata [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_rs3_rdata [RVFI_STAGES-1:0];
- logic [ 4:0] rvfi_stage_rd_addr [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_rd_wdata [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_pc_rdata [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_pc_wdata [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_mem_addr [RVFI_STAGES-1:0];
- logic [ 3:0] rvfi_stage_mem_rmask [RVFI_STAGES-1:0];
- logic [ 3:0] rvfi_stage_mem_wmask [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_mem_rdata [RVFI_STAGES-1:0];
- logic [31:0] rvfi_stage_mem_wdata [RVFI_STAGES-1:0];
+ logic rvfi_stage_valid [RVFI_STAGES];
+ logic [63:0] rvfi_stage_order [RVFI_STAGES];
+ logic [31:0] rvfi_stage_insn [RVFI_STAGES];
+ logic rvfi_stage_trap [RVFI_STAGES];
+ logic rvfi_stage_halt [RVFI_STAGES];
+ logic rvfi_stage_intr [RVFI_STAGES];
+ logic [ 1:0] rvfi_stage_mode [RVFI_STAGES];
+ logic [ 1:0] rvfi_stage_ixl [RVFI_STAGES];
+ logic [ 4:0] rvfi_stage_rs1_addr [RVFI_STAGES];
+ logic [ 4:0] rvfi_stage_rs2_addr [RVFI_STAGES];
+ logic [ 4:0] rvfi_stage_rs3_addr [RVFI_STAGES];
+ logic [31:0] rvfi_stage_rs1_rdata [RVFI_STAGES];
+ logic [31:0] rvfi_stage_rs2_rdata [RVFI_STAGES];
+ logic [31:0] rvfi_stage_rs3_rdata [RVFI_STAGES];
+ logic [ 4:0] rvfi_stage_rd_addr [RVFI_STAGES];
+ logic [31:0] rvfi_stage_rd_wdata [RVFI_STAGES];
+ logic [31:0] rvfi_stage_pc_rdata [RVFI_STAGES];
+ logic [31:0] rvfi_stage_pc_wdata [RVFI_STAGES];
+ logic [31:0] rvfi_stage_mem_addr [RVFI_STAGES];
+ logic [ 3:0] rvfi_stage_mem_rmask [RVFI_STAGES];
+ logic [ 3:0] rvfi_stage_mem_wmask [RVFI_STAGES];
+ logic [31:0] rvfi_stage_mem_rdata [RVFI_STAGES];
+ logic [31:0] rvfi_stage_mem_wdata [RVFI_STAGES];
- logic rvfi_stage_valid_d [RVFI_STAGES-1:0];
+ logic rvfi_stage_valid_d [RVFI_STAGES];
assign rvfi_valid = rvfi_stage_valid [RVFI_STAGES-1];
assign rvfi_order = rvfi_stage_order [RVFI_STAGES-1];
@@ -1019,7 +1027,7 @@
assign rvfi_mem_rdata = rvfi_stage_mem_rdata[RVFI_STAGES-1];
assign rvfi_mem_wdata = rvfi_stage_mem_wdata[RVFI_STAGES-1];
- if (WritebackStage) begin
+ if (WritebackStage) begin : gen_rvfi_wb_stage
logic unused_instr_new_id;
assign unused_instr_new_id = instr_new_id;
@@ -1046,7 +1054,7 @@
rvfi_instr_new_wb_q <= instr_id_done;
end
end
- end else begin
+ end else begin : gen_rvfi_no_wb_stage
// Without writeback stage first RVFI stage is output stage so simply valid the cycle after
// instruction leaves ID/EX (and so has retired)
assign rvfi_stage_valid_d[0] = instr_id_done & ~dummy_instr_id;
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_counter.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_counter.sv
index 2c0722f..465b931 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_counter.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_counter.sv
@@ -44,8 +44,8 @@
`ifdef FPGA_XILINX
// Set DSP pragma for supported xilinx FPGAs
- localparam dsp_pragma = CounterWidth < 49 ? "yes" : "no";
- (* use_dsp = dsp_pragma *) logic [CounterWidth-1:0] counter_q;
+ localparam int DspPragma = CounterWidth < 49 ? "yes" : "no";
+ (* use_dsp = DspPragma *) logic [CounterWidth-1:0] counter_q;
// DSP output register requires synchronous reset.
`define COUNTER_FLOP_RST posedge clk_i
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv
index b4df9bd..0b6f934 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv
@@ -137,12 +137,12 @@
priv_lvl_e mpp;
logic mprv;
logic tw;
- } Status_t;
+ } status_t;
typedef struct packed {
logic mpie;
priv_lvl_e mpp;
- } StatusStk_t;
+ } status_stk_t;
typedef struct packed {
x_debug_ver_e xdebugver;
@@ -160,7 +160,7 @@
logic nmip;
logic step;
priv_lvl_e prv;
- } Dcsr_t;
+ } dcsr_t;
// CPU control register fields
typedef struct packed {
@@ -169,14 +169,14 @@
logic dummy_instr_en;
logic data_ind_timing;
logic icache_enable;
- } CpuCtrl_t;
+ } cpu_ctrl_t;
// Interrupt and exception control signals
logic [31:0] exception_pc;
// CSRs
priv_lvl_e priv_lvl_q, priv_lvl_d;
- Status_t mstatus_q, mstatus_d;
+ status_t mstatus_q, mstatus_d;
irqs_t mie_q, mie_d;
logic [31:0] mscratch_q, mscratch_d;
logic [31:0] mepc_q, mepc_d;
@@ -184,14 +184,14 @@
logic [31:0] mtval_q, mtval_d;
logic [31:0] mtvec_q, mtvec_d;
irqs_t mip;
- Dcsr_t dcsr_q, dcsr_d;
+ dcsr_t dcsr_q, dcsr_d;
logic [31:0] depc_q, depc_d;
logic [31:0] dscratch0_q, dscratch0_d;
logic [31:0] dscratch1_q, dscratch1_d;
// CSRs for recoverable NMIs
// NOTE: these CSRS are nonstandard, see https://github.com/riscv/riscv-isa-manual/issues/261
- StatusStk_t mstack_q, mstack_d;
+ status_stk_t mstack_q, mstack_d;
logic [31:0] mstack_epc_q, mstack_epc_d;
logic [5:0] mstack_cause_q, mstack_cause_d;
@@ -221,7 +221,7 @@
logic [31:0] tmatch_value_rdata;
// CPU control bits
- CpuCtrl_t cpuctrl_rdata, cpuctrl_wdata;
+ cpu_ctrl_t cpuctrl_rdata, cpuctrl_wdata;
// CSR update logic
logic [31:0] csr_wdata_int;
@@ -685,7 +685,7 @@
mepc_q <= '0;
mcause_q <= '0;
mtval_q <= '0;
- mtvec_q <= 32'b01;
+ mtvec_q <= 32'h0000_0001;
dcsr_q <= '{
xdebugver: XDEBUGVER_STD,
cause: DBG_CAUSE_NONE, // 3'h0
@@ -1054,7 +1054,7 @@
// CPU control fields
assign cpuctrl_rdata.unused_ctrl = '0;
// Cast register write data
- assign cpuctrl_wdata = CpuCtrl_t'(csr_wdata_int);
+ assign cpuctrl_wdata = cpu_ctrl_t'(csr_wdata_int);
// Generate fixed time execution bit
if (DataIndTiming) begin : gen_dit
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_decoder.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_decoder.sv
index 96acd3d..b895275 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_decoder.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_decoder.sv
@@ -3,11 +3,6 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
-// Source/Destination register instruction index
-`define REG_S1 19:15
-`define REG_S2 24:20
-`define REG_S3 31:27
-`define REG_D 11:07
/**
* Instruction decoder
@@ -111,6 +106,11 @@
logic [31:0] instr;
logic [31:0] instr_alu;
+ // Source/Destination register instruction index
+ logic [4:0] instr_rs1;
+ logic [4:0] instr_rs2;
+ logic [4:0] instr_rs3;
+ logic [4:0] instr_rd;
logic use_rs3;
@@ -137,14 +137,18 @@
assign imm_j_type_o = { {12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0 };
// immediate for CSR manipulation (zero extended)
- assign zimm_rs1_type_o = { 27'b0, instr[`REG_S1] }; // rs1
+ assign zimm_rs1_type_o = { 27'b0, instr_rs1 }; // rs1
// source registers
- assign rf_raddr_a_o = use_rs3 ? instr[`REG_S3] : instr[`REG_S1]; // rs3 / rs1
- assign rf_raddr_b_o = instr[`REG_S2]; // rs2
+ assign instr_rs1 = instr[19:15];
+ assign instr_rs2 = instr[24:20];
+ assign instr_rs3 = instr[31:27];
+ assign rf_raddr_a_o = use_rs3 ? instr_rs3 : instr_rs1; // rs3 / rs1
+ assign rf_raddr_b_o = instr_rs2; // rs2
// destination register
- assign rf_waddr_o = instr[`REG_D]; // rd
+ assign instr_rd = instr[11:7];
+ assign rf_waddr_o = instr_rd; // rd
////////////////////
// Register check //
@@ -166,7 +170,7 @@
// CSRRSI/CSRRCI must not write 0 to CSRs (uimm[4:0]=='0)
// CSRRS/CSRRC must not write from x0 to CSRs (rs1=='0)
if ((csr_op == CSR_OP_SET || csr_op == CSR_OP_CLEAR) &&
- instr[`REG_S1] == '0) begin
+ instr_rs1 == '0) begin
csr_op_o = CSR_OP_READ;
end
end
@@ -555,7 +559,7 @@
endcase
// rs1 and rd must be 0
- if (instr[`REG_S1] != 5'b0 || instr[`REG_D] != 5'b0) begin
+ if (instr_rs1 != 5'b0 || instr_rd != 5'b0) begin
illegal_insn = 1'b1;
end
end else begin
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_icache.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_icache.sv
index f65725b..e606a41 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_icache.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_icache.sv
@@ -562,9 +562,8 @@
(fill_cache_q[fb] & fill_busy_q[fb] &
icache_enable_i & ~icache_inval_i);
// Record whether the request hit in the cache
- assign fill_hit_ic1[fb] = lookup_valid_ic1 & fill_in_ic1[fb] & tag_hit_ic1;
- assign fill_hit_d[fb] = (fill_hit_ic1[fb] & ~ecc_err_ic1) |
- (fill_hit_q[fb] & fill_busy_q[fb]);
+ assign fill_hit_ic1[fb] = lookup_valid_ic1 & fill_in_ic1[fb] & tag_hit_ic1 & ~ecc_err_ic1;
+ assign fill_hit_d[fb] = fill_hit_ic1[fb] | (fill_hit_q[fb] & fill_busy_q[fb]);
///////////////////////////////////////////
// Fill buffer external request tracking //
@@ -585,7 +584,7 @@
// External requests are completed when the counter is filled or when the request is cancelled
assign fill_ext_done[fb] = (fill_ext_cnt_q[fb][LINE_BEATS_W] |
// external requests are considered complete if the request hit
- (fill_hit_ic1[fb] & ~ecc_err_ic1) | fill_hit_q[fb] |
+ fill_hit_ic1[fb] | fill_hit_q[fb] |
// external requests will stop once any PMP error is received
fill_err_q[fb][fill_ext_off[fb]] |
// cancel if the line is stale and won't be cached
@@ -618,7 +617,7 @@
(fill_rvd_beat[fb] > fill_out_cnt_q[fb]) | fill_rvd_arb[fb]);
// Calculate when a beat of data is output. Any ECC error squashes the output that cycle.
- assign fill_out_grant[fb] = fill_out_arb[fb] & output_ready & ~ecc_err_ic1;
+ assign fill_out_grant[fb] = fill_out_arb[fb] & output_ready;
// Count the beats of data output to the IF stage
assign fill_out_cnt_d[fb] = fill_alloc[fb] ? {1'b0,lookup_addr_ic0[LINE_W-1:BUS_W]} :
@@ -742,8 +741,8 @@
// Data either comes from the cache or the bus. If there was an ECC error, we must take
// the incoming bus data since the cache hit data is corrupted.
- assign fill_data_d[fb] = (fill_hit_ic1[fb] & ~ecc_err_ic1) ? hit_data_ic1[LineSize-1:0] :
- {LINE_BEATS{instr_rdata_i}};
+ assign fill_data_d[fb] = fill_hit_ic1[fb] ? hit_data_ic1[LineSize-1:0] :
+ {LINE_BEATS{instr_rdata_i}};
for (genvar b = 0; b < LINE_BEATS; b++) begin : gen_data_buf
// Error tracking (per beat)
@@ -865,8 +864,7 @@
// Output data is valid (from any of the three possible sources). Note that fill_out_arb
// must be used here rather than fill_out_req because data can become valid out of order
// (e.g. cache hit data can become available ahead of an older outstanding miss).
- // Any ECC error suppresses the output that cycle.
- assign data_valid = |fill_out_arb & ~ecc_err_ic1;
+ assign data_valid = |fill_out_arb;
// Skid buffer data
assign skid_data_d = output_data[31:16];
@@ -1017,4 +1015,8 @@
`ASSERT_INIT(ecc_tag_param_legal, (TAG_SIZE <= 27))
`ASSERT_INIT(ecc_data_param_legal, (LineSize <= 121))
+ // Lookups in the tag ram should always give a known result
+ `ASSERT_KNOWN(TagHitKnown, lookup_valid_ic1 & tag_hit_ic1)
+ `ASSERT_KNOWN(TagInvalidKnown, lookup_valid_ic1 & tag_invalid_ic1)
+
endmodule
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv
index f976b77..ee63142 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv
@@ -28,7 +28,6 @@
input logic clk_i,
input logic rst_ni,
- input logic fetch_enable_i,
output logic ctrl_busy_o,
output logic illegal_insn_o,
@@ -526,7 +525,6 @@
.clk_i ( clk_i ),
.rst_ni ( rst_ni ),
- .fetch_enable_i ( fetch_enable_i ),
.ctrl_busy_o ( ctrl_busy_o ),
// decoder related signals
@@ -816,12 +814,6 @@
assign instr_done = ~stall_id & ~flush_id & instr_executing;
- if (WritebackStage) begin
- assign multicycle_done = lsu_req_dec ? ~stall_mem : ex_valid_i;
- end else begin
- assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i;
- end
-
// Signal instruction in ID is in it's first cycle. It can remain in its
// first cycle if it is stalled.
assign instr_first_cycle = instr_valid_i & (id_fsm_q == FIRST_CYCLE);
@@ -841,6 +833,8 @@
logic instr_kill;
+ assign multicycle_done = lsu_req_dec ? ~stall_mem : ex_valid_i;
+
// Is a memory access ongoing that isn't finishing this cycle
assign outstanding_memory_access = (outstanding_load_wb_i | outstanding_store_wb_i) &
~lsu_resp_valid_i;
@@ -920,7 +914,9 @@
assign stall_wb = en_wb_o & ~ready_wb_i;
assign perf_dside_wait_o = instr_valid_i & ~instr_kill & (outstanding_memory_access | stall_ld_hz);
- end else begin
+ end else begin : gen_no_stall_mem
+
+ assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i;
assign data_req_allowed = instr_first_cycle;
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_ff.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_ff.sv
index 715a97c..4dd429d 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_ff.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_ff.sv
@@ -42,7 +42,7 @@
localparam int unsigned NUM_WORDS = 2**ADDR_WIDTH;
logic [NUM_WORDS-1:0][DataWidth-1:0] rf_reg;
- logic [NUM_WORDS-1:1][DataWidth-1:0] rf_reg_tmp;
+ logic [NUM_WORDS-1:1][DataWidth-1:0] rf_reg_q;
logic [NUM_WORDS-1:1] we_a_dec;
always_comb begin : we_a_decoder
@@ -51,13 +51,13 @@
end
end
- // loop from 1 to NUM_WORDS-1 as R0 is nil
- always_ff @(posedge clk_i or negedge rst_ni) begin
- if (!rst_ni) begin
- rf_reg_tmp <= '{default:'0};
- end else begin
- for (int r = 1; r < NUM_WORDS; r++) begin
- if (we_a_dec[r]) rf_reg_tmp[r] <= wdata_a_i;
+ // No flops for R0 as it's hard-wired to 0
+ for (genvar i = 1; i < NUM_WORDS; i++) begin : g_rf_flops
+ always_ff @(posedge clk_i or negedge rst_ni) begin
+ if (!rst_ni) begin
+ rf_reg_q[i] <= '0;
+ end else if(we_a_dec[i]) begin
+ rf_reg_q[i] <= wdata_a_i;
end
end
end
@@ -66,21 +66,21 @@
// real instructions.
if (DummyInstructions) begin : g_dummy_r0
logic we_r0_dummy;
- logic [31:0] rf_r0;
+ logic [31:0] rf_r0_q;
// Write enable for dummy R0 register (waddr_a_i will always be 0 for dummy instructions)
assign we_r0_dummy = we_a_i & dummy_instr_id_i;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
- rf_r0 <= '0;
+ rf_r0_q <= '0;
end else if (we_r0_dummy) begin
- rf_r0 <= wdata_a_i;
+ rf_r0_q <= wdata_a_i;
end
end
// Output the dummy data for dummy instructions, otherwise R0 reads as zero
- assign rf_reg[0] = dummy_instr_id_i ? rf_r0 : '0;
+ assign rf_reg[0] = dummy_instr_id_i ? rf_r0_q : '0;
end else begin : g_normal_r0
logic unused_dummy_instr_id;
@@ -90,7 +90,7 @@
assign rf_reg[0] = '0;
end
- assign rf_reg[NUM_WORDS-1:1] = rf_reg_tmp[NUM_WORDS-1:1];
+ assign rf_reg[NUM_WORDS-1:1] = rf_reg_q[NUM_WORDS-1:1];
assign rdata_a_o = rf_reg[raddr_a_i];
assign rdata_b_o = rf_reg[raddr_b_i];
diff --git a/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_latch.sv b/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_latch.sv
index 5b99761..7cc4446 100644
--- a/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_latch.sv
+++ b/hw/vendor/lowrisc_ibex/rtl/ibex_register_file_latch.sv
@@ -109,11 +109,11 @@
// Actual write operation:
// Generate the sequential process for the NUM_WORDS words of the memory.
- // The process is synchronized with the clocks mem_clocks[k], k = 1, ..., NUM_WORDS-1.
- always_latch begin : latch_wdata
- for (int k = 1; k < NUM_WORDS; k++) begin : latch_wdata_word_iter
- if (mem_clocks[k]) begin
- mem[k] = wdata_a_q;
+ // The process is synchronized with the clocks mem_clocks[i], i = 1, ..., NUM_WORDS-1.
+ for (genvar i = 1; i < NUM_WORDS; i++) begin : g_rf_latches
+ always_latch begin
+ if (mem_clocks[i]) begin
+ mem[i] = wdata_a_q;
end
end
end
diff --git a/hw/vendor/lowrisc_ibex/syn/lec_sv2v.do b/hw/vendor/lowrisc_ibex/syn/lec_sv2v.do
new file mode 100644
index 0000000..7dba52c
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/syn/lec_sv2v.do
@@ -0,0 +1,55 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// LEC dofile for script lec_sv2v.sh. A similar script is used in
+// OpenTitan, any updates or fixes here may need to be reflected in the
+// OpenTitan script as well:
+// https://github.com/lowRISC/opentitan/blob/master/hw/formal/lec_sv2v.do
+
+//-------------------------------------------------------------------------
+// read in golden (SystemVerilog) and revised (Verilog)
+//-------------------------------------------------------------------------
+
+// map all multi-dimensional ports (including structs) onto 1-dim. ports
+set naming rule -mdportflatten
+
+read design -golden -sv09 -f flist_gold -rootonly -root $LEC_TOP
+read design -revised -sys -f flist_rev -rootonly -root $LEC_TOP
+// TODO: instead of using switch -sys (for old SystemVerilog,
+// older than sv2009) we should use -ve (for Verilog). But
+// this currently doesn't work because sv2v doesn't translate
+// .* port connections. Is that an sv2v bug?
+
+//-------------------------------------------------------------------------
+// pre-LEC reports
+//-------------------------------------------------------------------------
+report rule check -verbose
+report design data
+report black box
+report module
+
+//-------------------------------------------------------------------------
+// compare
+//-------------------------------------------------------------------------
+set system mode lec
+set parallel option -threads 8
+
+// map unreachable points
+set mapping method -nets -mem -unreach
+map key points
+report unmapped points
+
+add compare point -all
+compare -threads 8 -noneq_stop 1
+analyze abort -compare
+
+//-------------------------------------------------------------------------
+// reports
+//-------------------------------------------------------------------------
+report compare data -class nonequivalent -class abort -class notcompared
+report verification -verbose
+report statistics
+usage
+
+exit -force
diff --git a/hw/vendor/lowrisc_ibex/syn/lec_sv2v.sh b/hw/vendor/lowrisc_ibex/syn/lec_sv2v.sh
new file mode 100755
index 0000000..089f428
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/syn/lec_sv2v.sh
@@ -0,0 +1,87 @@
+#!/bin/bash
+
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+# This script converts all SystemVerilog RTL files to Verilog
+# using sv2v and then runs LEC (Cadence Conformal) to check if
+# the generated Verilog is logically equivalent to the original
+# SystemVerilog. A similar script is used in OpenTitan, any updates
+# or fixes here may need to be reflected in the OpenTitan script as well
+# https://github.com/lowRISC/opentitan/blob/master/util/syn_yosys.sh
+#
+# The following tools are required:
+# - sv2v: SystemVerilog-to-Verilog converter from github.com/zachjs/sv2v
+# - Cadence Conformal
+#
+# Usage:
+# ./lec_sv2v.sh |& tee lec.log
+
+#-------------------------------------------------------------------------
+# use fusesoc to generate files and file list
+#-------------------------------------------------------------------------
+rm -Rf build lec_out
+fusesoc --cores-root .. run --tool=icarus --target=lint \
+ --setup "lowrisc:ibex:ibex_core" > /dev/null 2>&1
+
+# copy all files to lec_out
+mkdir lec_out
+cp build/*/src/*/*.sv build/*/src/*/*/*.sv lec_out
+cd lec_out
+
+# copy file list and remove incdir, RVFI define, and sim-file
+egrep -v 'incdir|RVFI|simulator_ctrl' ../build/*/*/*.scr > flist_gold
+
+# remove all hierarchical paths
+sed -i 's!.*/!!' flist_gold
+
+# generate revised flist by replacing '.sv' by '.v' and removing packages
+sed 's/.sv/.v/' flist_gold | grep -v "_pkg.v" > flist_rev
+
+#-------------------------------------------------------------------------
+# convert all RTL files to Verilog using sv2v
+#-------------------------------------------------------------------------
+printf "\nSV2V ERRORS:\n"
+
+for file in *.sv; do
+ module=`basename -s .sv $file`
+ sv2v --define=SYNTHESIS *_pkg.sv prim_assert.sv $file > ${module}.v
+done
+
+# remove *pkg.v files (they are empty files and not needed)
+rm -f *_pkg.v prim_assert.v prim_util_memload.v
+
+# overwrite the prim_clock_gating modules with the module from ../rtl
+cp ../rtl/prim_clock_gating.v .
+cp ../rtl/prim_clock_gating.v prim_clock_gating.sv
+
+#-------------------------------------------------------------------------
+# run LEC (generated Verilog vs. original SystemVerilog)
+#-------------------------------------------------------------------------
+printf "\n\nLEC RESULTS:\n"
+
+for file in *.v; do
+ export LEC_TOP=`basename -s .v $file`
+
+ # special case is file ibex_register_file_ff.sv, whose module has a
+ # different name than its file name
+ if [[ $LEC_TOP == "ibex_register_file_ff" ]]; then
+ export LEC_TOP="ibex_register_file"
+ fi
+
+ # run Conformal LEC
+ lec -xl -nogui -nobanner \
+ -dofile ../lec_sv2v.do \
+ -logfile lec_${LEC_TOP}.log \
+ <<< "exit -force" > /dev/null 2>&1
+
+ # summarize results
+ check=`grep "Compare Results" lec_${LEC_TOP}.log`
+ if [ $? -ne 0 ]; then
+ result="CRASH"
+ else
+ result=`echo $check | awk '{ print $4 }'`
+ fi
+ printf "%-25s %s\n" $LEC_TOP $result
+done
diff --git a/hw/vendor/lowrisc_ibex/util/ibex_config.py b/hw/vendor/lowrisc_ibex/util/ibex_config.py
index 1aa6fcf..1329e71 100755
--- a/hw/vendor/lowrisc_ibex/util/ibex_config.py
+++ b/hw/vendor/lowrisc_ibex/util/ibex_config.py
@@ -226,6 +226,12 @@
SimOpts('riviera_compile_opts', 'Riviera compile',
lambda p, v: None,
lambda d, v: '+define+' + d + '=' + v, '/'),
+ SimOpts('questa_sim_opts', 'Questa simulate',
+ lambda p, v: '-g/' + p + '=' + v,
+ lambda d, v: None, '/'),
+ SimOpts('questa_compile_opts', 'Questa compile',
+ lambda p, v: None,
+ lambda d, v: '+define+' + d + '=' + v, '/'),
SimOpts('xlm_opts', 'Xcelium compile',
lambda p, v: '-defparam ' + p + '=' + v,
lambda d, v: '-define ' + d + '=' + v, '.'),
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv.lock.hjson b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv.lock.hjson
index fdfbb51..57ed1a9 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv.lock.hjson
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv.lock.hjson
@@ -9,6 +9,6 @@
upstream:
{
url: https://github.com/google/riscv-dv
- rev: 1ad73cc43f8f84d93d49040f8b2928e74efdd854
+ rev: 6cf6b4f389272d8ff5e2b397af43ac6c0dfba2e2
}
}
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/.flake8 b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/.flake8
new file mode 100644
index 0000000..5b0913f
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/.flake8
@@ -0,0 +1,10 @@
+[flake8]
+
+# Maximum line length
+max-line-length = 100
+
+ignore =
+ # Ignore unexpected spaces around keyword / parameter equals
+ E251,
+ # Do not complain about line breaks after operators
+ W504
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/.travis.yml b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/.travis.yml
index dada2b9..2c25db4 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/.travis.yml
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/.travis.yml
@@ -2,8 +2,6 @@
dist: xenial
matrix:
include:
- - python: 3.5
- env: TOX_ENV=py35
- python: 3.6
env: TOX_ENV=py36
- python: 3.7
@@ -15,3 +13,4 @@
script:
- sphinx-build -E -W -b linkcheck docs/source build
- pip uninstall -y riscv-dv
+ - flake8 --show-source pygen/pygen_src/ --config=.flake8
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py
new file mode 100644
index 0000000..8392a3c
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/isa/riscv_instr.py
@@ -0,0 +1,408 @@
+"""
+Copyright 2020 Google LLC
+Copyright 2020 PerfectVIPs Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+Regression script for RISC-V random instruction generator
+
+"""
+
+
+from collections import defaultdict
+from pygen_src.riscv_instr_gen_config import riscv_instr_gen_config
+from pygen_src.riscv_instr_pkg import riscv_instr_group_t
+from pygen_src.isa import rv32i_instr # NOQA
+import random
+from bitstring import BitArray
+import logging
+from copy import copy
+import sys
+
+
+class riscv_instr:
+
+ logging.basicConfig(level=logging.INFO)
+ instr_registry = {}
+
+ def __init__(self):
+ self.instr_names = []
+ self.instr_group = defaultdict(list)
+ self.instr_category = defaultdict(list)
+ self.basic_instr = []
+ self.instr_template = {}
+
+ self.exclude_reg = []
+ self.include_reg = []
+
+ self.group = None
+ self.format = None
+ self.category = None
+ self.instr_name = None
+ self.imm_type = None
+ self.imm_len = 0
+
+ self.csr = None
+ self.rs2 = None
+ self.rs1 = None
+ self.rd = None
+ self.imm = BitArray(hex="0x00000000")
+
+ self.imm_mask = BitArray(hex="0xffffffff")
+ self.is_branch_target = None
+ self.has_label = 1
+ self.atomic = 0
+ self.branch_assigned = None
+ self.process_load_store = 1
+ self.is_compressed = None
+ self.is_illegal_instr = None
+ self.is_hint_instr = None
+ self.is_floating_point = None
+ self.imm_str = None
+ self.comment = None
+ self.label = None
+ self.is_local_numeric_label = None
+ self.idx = -1
+ self.has_rs1 = 1
+ self.has_rs2 = 1
+ self.has_rd = 1
+ self.has_imm = 1
+
+ # Fields Added for debugging These fields are actually from a different files.
+ self.unsupported_instr = []
+ self.XLEN = 32
+ self.supported_isa = [riscv_instr_group_t.RV32I]
+ self.implemented_csr = []
+
+ @classmethod
+ def register(cls, instr_name):
+ logging.info("Registering %s", instr_name.name)
+ cls.instr_registry[instr_name.name] = 1
+ if(instr_name is None):
+ print("\n")
+ return 1
+
+ def create_instr_list(self, cfg):
+ self.instr_names.clear()
+ self.instr_group.clear()
+ self.instr_category.clear()
+ for instr_name, values in self.instr_registry.items():
+ if(instr_name in self.unsupported_instr):
+ continue
+ instr_inst = self.create_instr(instr_name)
+ self.instr_template[instr_name] = instr_inst
+
+ if (not instr_inst.is_supported(cfg)):
+ continue
+ if ((self.XLEN != 32) and (instr_name == "C_JAL")):
+ continue
+ if (("SP" in cfg.reserved_regs) and (instr_name == "C_ADDI16SP")):
+ continue
+ if (cfg.enable_sfence and instr_name == "SFENCE_VMA"):
+ continue
+ if (instr_name in ["FENCE", "FENCE_I", "SFENCE_VMA"]):
+ continue
+ if (instr_inst.group in self.supported_isa and
+ not(cfg.disable_compressed_instr and
+ instr_inst.group in ["RV32C", "RV64C", "RV32DC", "RV32FC", "RV128C"]) and
+ not(not(cfg.enable_floating_point) and instr_inst.group in
+ ["RV32F", "RV64F", "RV32D", "RV64D"])):
+ self.instr_category[instr_inst.category.name].append(instr_name)
+ self.instr_group[instr_inst.group.name].append(instr_name)
+ self.instr_names.append(instr_name)
+
+ self.build_basic_instruction_list(cfg)
+ self.create_csr_filter(cfg)
+
+ def create_instr(self, instr_name):
+ """TODO This method is specific to RV32I instruction only.
+ It must be scaled to all instruction extensions."""
+ try:
+ instr_inst = eval("rv32i_instr.riscv_" + instr_name + "_instr()")
+ except Exception:
+ logging.critical("Failed to create instr: %0s", instr_name)
+ sys.exit(1)
+ return instr_inst
+
+ def is_supported(self, cfg):
+ return 1
+
+ def build_basic_instruction_list(self, cfg):
+ self.basic_instr = (self.instr_category["SHIFT"] + self.instr_category["ARITHMETIC"] +
+ self.instr_category["LOGICAL"] + self.instr_category["COMPARE"])
+ if(cfg.no_ebreak == 0):
+ self.basic_instr.append("EBREAK")
+ for items in self.supported_isa:
+ if("RV32C" in self.supported_isa and not(cfg.disable_compressed_instr)):
+ self.basic_instr.append("C_EBREAK")
+ break
+ if(cfg.no_dret == 0):
+ self.basic_instr.append("DRET")
+ if(cfg.no_fence == 0):
+ self.basic_instr.append(self.instr_category["SYNCH"])
+ if(cfg.no_csr_instr == 0 and cfg.init_privileged_mode == "MACHINE_MODE"):
+ self.basic_instr.append(self.instr_category["CSR"])
+ if(cfg.no_wfi == 0):
+ self.basic_instr.append("WFI")
+
+ def create_csr_filter(self, cfg):
+ self.include_reg.clear()
+ self.exclude_reg.clear()
+
+ if(cfg.enable_illegal_csr_instruction):
+ self.exclude_reg = self.implemented_csr
+ elif(cfg.enable_access_invalid_csr_level):
+ self.include_reg = cfg.invalid_priv_mode_csrs
+ else:
+ if(cfg.init_privileged_mode == "MACHINE_MODE"): # Machine Mode
+ self.include_reg.append("MSCRATCH")
+ elif(cfg.init_privileged_mode == "SUPERVISOR_MODE"): # Supervisor Mode
+ self.include_reg.append("SSCRATCH")
+ else: # User Mode
+ self.include_reg.append("USCRATCH")
+
+ def get_rand_instr(self, include_instr=[], exclude_instr=[],
+ include_category=[], exclude_category=[],
+ include_group=[], exclude_group=[]):
+ idx = BitArray(uint = 0, length = 32)
+ name = ""
+ allowed_instr = []
+ disallowed_instr = []
+ # allowed_categories = []
+
+ for items in include_category:
+ allowed_instr.append(self.instr_category[items])
+
+ for items in exclude_category:
+ if(items in self.instr_category):
+ disallowed_instr.append(self.instr_category[items])
+ for items in include_group:
+ allowed_instr.append(self.instr_group[items])
+ for items in exclude_group:
+ if(items in self.instr_group):
+ disallowed_instr.append(self.instr_group[items])
+
+ disallowed_instr.extend(exclude_instr)
+
+ if(len(disallowed_instr) == 0):
+ if(len(include_instr) > 0):
+ idx = random.randrange(0, len(include_instr) - 1)
+ name = include_instr[idx]
+ elif(len(allowed_instr > 0)):
+ idx = random.randrange(0, len(allowed_instr) - 1)
+ name = allowed_instr[idx]
+ else:
+ idx = random.randrange(0, len(self.instr_names) - 1)
+ name = self.instr_names[idx]
+ else:
+ # TODO
+ instr_names_set = set(self.instr_names)
+ disallowed_instr_set = set(disallowed_instr)
+ allowed_instr_set = set(allowed_instr)
+ include_instr_set = set(include_instr)
+ excluded_instr_names_list = list(instr_names_set - disallowed_instr_set)
+ excluded_allowed_instr_list = list(allowed_instr_set - disallowed_instr_set)
+ include_instr_list = list(include_instr_set - disallowed_instr_set)
+
+ name = random.choice(excluded_instr_names_list)
+ if(len(include_instr) > 0):
+ name = random.choice(include_instr_list)
+ if(len(allowed_instr) > 0):
+ name = random.choice(excluded_allowed_instr_list)
+ if(name is None):
+ logging.critical("%s Cannot generate random instruction", riscv_instr.__name__)
+ sys.exit(1)
+
+ instr_h = copy(self.instr_template[name])
+ return instr_h
+
+ def get_load_store_instr(self, load_store_instr):
+ instr_h = riscv_instr()
+ if(len(load_store_instr) == 0):
+ load_store_instr = self.instr_category["LOAD"] + \
+ self.instr_category["STORE"]
+ self.idx = random.randrange(0, len(load_store_instr) - 1)
+ name = load_store_instr[self.idx]
+ instr_h = copy(self.instr_template[name])
+ return instr_h
+
+ def get_instr(self, name):
+ if (not self.instr_template.get(name)):
+ logging.critical("Cannot get instr %s", name)
+ instr_h = copy(self.instr_template[name])
+ return instr_h
+
+ def set_rand_mode(self):
+ # rand_mode setting for Instruction Format
+ if(self.format.name == "R_FORMAT"):
+ self.has_imm = 0
+ if(self.format.name == "I_FORMAT"):
+ self.has_rs2 = 0
+ if(self.format.name in ["S_FORMAT", "B_FORMAT"]):
+ self.has_rd = 0
+ if(self.format.name in ["U_FORMAT", "J_FORMAT"]):
+ self.has_rs1 = 0
+ self.has_rs2 = 0
+
+ # rand_mode setting for Instruction Category
+ if(self.category.name == "CSR"):
+ self.has_rs2 = 0
+ if(self.format.name == "I_FORMAT"):
+ self.has_rs1 = 0
+
+ def pre_randomize(self):
+ pass # TODO
+
+ def set_imm_len(self):
+ if(self.format.name in ["U_FORMAT", "J_FORMAT"]):
+ self.imm_len = 20
+ elif(self.format.name in ["I_FORMAT", "S_FORMAT", "B_FORMAT"]):
+ if(self.imm_type.name == "UIMM"):
+ self.imm_len = 5
+ else:
+ self.imm_len = 11
+ self.imm_mask = self.imm_mask << self.imm_len
+
+ def extend_imm(self):
+ sign = 0
+ self.imm = self.imm << (32 - self.imm_len)
+ # sign = imm[31]
+ sign = self.imm.bin[0:1:1]
+ self.imm = self.imm >> (32 - self.imm_len)
+ # Signed extension
+ if((sign and not(self.format == "U_FORMAT")) or (self.imm_type in ["UIMM", "NZUIMM"])):
+ self.imm = self.imm_mask | self.imm
+
+ def post_randomize(self):
+ self.extend_imm()
+ self.update_imm_str()
+
+ def convert2asm(self):
+ pass
+
+ def get_opcode(self):
+ if(self.instr_name.name == "LUI"):
+ return (BitArray(uint = 55, length = 7).bin)
+ elif(self.instr_name.name == "AUIPC"):
+ return (BitArray(uint = 23, length = 7).bin)
+ elif(self.instr_name.name == "JAL"):
+ return (BitArray(uint = 23, length = 7).bin)
+ elif(self.instr_name.name == "JALR"):
+ return (BitArray(uint = 111, length = 7).bin)
+ elif(self.instr_name.name in ["BEQ", "BNE", "BLT", "BGE", "BLTU", "BGEU"]):
+ return (BitArray(uint = 103, length = 7).bin)
+ elif(self.instr_name.name in ["LB", "LH", "LW", "LBU", "LHU", "LWU", "LD"]):
+ return (BitArray(uint = 99, length = 7).bin)
+ elif(self.instr_name.name in ["SB", "SH", "SW", "SD"]):
+ return (BitArray(uint = 35, length = 7).bin)
+ elif(self.instr_name.name in ["ADDI", "SLTI", "SLTIU", "XORI", "ORI", "ANDI",
+ "SLLI", "SRLI", "SRAI", "NOP"]):
+ return (BitArray(uint = 19, length = 7).bin)
+ elif(self.instr_name.name in ["ADD", "SUB", "SLL", "SLT", "SLTU", "XOR", "SRL",
+ "SRA", "OR", "AND", "MUL", "MULH", "MULHSU", "MULHU",
+ "DIV", "DIVU", "REM", "REMU"]):
+ return (BitArray(uint = 51, length = 7).bin)
+ elif(self.instr_name.name in ["ADDIW", "SLLIW", "SRLIW", "SRAIW"]):
+ return (BitArray(uint = 27, length = 7).bin)
+ elif(self.instr_name.name in ["MULH", "MULHSU", "MULHU", "DIV", "DIVU", "REM", "REMU"]):
+ return (BitArray(uint = 51, length = 7).bin)
+ elif(self.instr_name.name in ["FENCE", "FENCE_I"]):
+ return (BitArray(uint = 15, length = 7).bin)
+ elif(self.instr_name.name in ["ECALL", "EBREAK", "CSRRW", "CSRRS", "CSRRC", "CSRRWI",
+ "CSRRSI", "CSRRCI"]):
+ return (BitArray(uint = 115, length = 7).bin)
+ elif(self.instr_name.name in ["ADDW", "SUBW", "SLLW", "SRLW", "SRAW", "MULW", "DIVW",
+ "DIVUW", "REMW", "REMUW"]):
+ return (BitArray(uint = 59, length = 7).bin)
+ elif(self.instr_name.name in ["ECALL", "EBREAK", "URET", "SRET", "MRET", "DRET", "WFI",
+ "SFENCE_VMA"]):
+ return (BitArray(uint = 115, length = 7).bin)
+ else:
+ logging.critical("Unsupported instruction %0s", self.instr_name.name)
+ sys.exit(1)
+
+ def get_func3(self):
+ if(self.instr_name.name in ["JALR", "BEQ", "LB", "SB", "ADDI", "NOP", "ADD", "SUB",
+ "FENCE", "ECALL", "EBREAK", "ADDIW", "ADDW", "SUBW", "MUL",
+ "MULW", "ECALL", "EBREAK", "URET", "SRET", "MRET", "DRET",
+ "WFI", "SFENCE_VMA"]):
+ return (BitArray(uint = 0, length = 3).bin)
+ elif(self.instr_name.name in ["BNE", "LH", "SH", "SLLI", "SLL", "FENCE_I", "CSRRW", "SLLIW",
+ "SLLW", "MULH"]):
+ return (BitArray(uint = 1, length = 3).bin)
+ elif(self.instr_name.name in ["LW", "SW", "SLTI", "SLT", "CSRRS", "MULHS"]):
+ return (BitArray(uint = 2, length = 3).bin)
+ elif(self.instr_name.name in ["SLTIU", "SLTU", "CSRRC", "LD", "SD", "MULHU"]):
+ return (BitArray(uint = 3, length = 3).bin)
+ elif(self.instr_name.name in ["BLT", "LBU", "XORI", "XOR", "DIV", "DIVW"]):
+ return (BitArray(uint = 4, length = 3).bin)
+ elif(self.instr_name.name in ["BGE", "LHU", "SRLI", "SRAI", "SRL", "SRA", "CSRRWI", "SRLIW",
+ "SRAIW", "SRLW",
+ "SRAW", "DIVU", "DIVUW"]):
+ return (BitArray(uint = 5, length = 3).bin)
+ elif(self.instr_name.name in ["BLTU", "ORI", "OR", "CSRRSI", "LWU", "REM", "REMW"]):
+ return (BitArray(uint = 6, length = 3).bin)
+ elif(self.instr_name.name in ["BGEU", "ANDI", "AND", "CSRRCI", "REMU", "REMUW"]):
+ return (BitArray(uint = 7, length = 3).bin)
+ else:
+ logging.critical("Unsupported instruction %0s", self.instr_name.name)
+ sys.exit(1)
+
+ def get_func7(self):
+ if(self.instr_name.name in ["SLLI", "SRLI", "ADD", "SLL", "SLT", "SLTU", "XOR",
+ "SRL", "OR", "AND", "FENCE", "FENCE_I", "SLLIW",
+ "SRLIW", "ADDW", "SLLW", "SRLW", "ECALL", "EBREAK", "URET"]):
+ return (BitArray(uint = 0, length = 7).bin)
+ elif(self.instr_name.name in ["SUB", "SRA", "SRAIW", "SUBW", "SRAW"]):
+ return (BitArray(uint = 32, length = 7).bin)
+ elif(self.instr_name.name in ["MUL", "MULH", "MULHSU", "MULHU", "DIV", "DIVU", "REM",
+ "REMU", "MULW", "DIVW", "DIVUW", "REMW", "REMUW"]):
+ return (BitArray(uint = 1, length = 7).bin)
+ elif(self.instr_name.name in ["SRET", "WFI"]):
+ return (BitArray(uint = 8, length = 7).bin)
+ elif(self.instr_name.name == "MRET"):
+ return (BitArray(uint = 24, length = 7).bin)
+ elif(self.instr_name.name == "DRET"):
+ return (BitArray(uint = 61, length = 7).bin)
+ elif(self.instr_name.name == "SFENCE_VMA"):
+ return (BitArray(uint = 9, length = 7).bin)
+ else:
+ logging.critical("Unsupported instruction %0s", self.instr_name.name)
+ sys.exit(1)
+
+ def convert2bin(self):
+ pass # TODO
+
+ def get_instr_name(self):
+ get_instr_name = self.instr_name.name
+ for i in get_instr_name:
+ if(i == "_"):
+ get_instr_name = get_instr_name.replace(i, ".")
+ return get_instr_name
+
+ def get_c_gpr(self, gpr):
+ return self.gpr
+
+ def get_imm(self):
+ return self.imm_str
+
+ def clear_unused_label(self):
+ if(self.has_label and not(self.is_branch_target) and self.is_local_numeric_label):
+ self.has_label = 0
+
+ def do_copy(self):
+ pass # TODO
+
+ def update_imm_str(self):
+ self.imm_str = str(self.imm)
+
+
+riscv_instr_ins = riscv_instr()
+cfg = riscv_instr_gen_config()
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32i_instr.py b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32i_instr.py
new file mode 100644
index 0000000..a7ed7ac
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/isa/rv32i_instr.py
@@ -0,0 +1,141 @@
+"""
+Copyright 2020 Google LLC
+Copyright 2020 PerfectVIPs Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+Regression script for RISC-V random instruction generator
+
+"""
+
+from pygen_src.riscv_defines import DEFINE_INSTR
+from pygen_src.riscv_instr_pkg import (riscv_instr_name_t, riscv_instr_format_t,
+ riscv_instr_category_t, riscv_instr_group_t, imm_t)
+
+
+# LOAD instructions
+DEFINE_INSTR(riscv_instr_name_t.LB, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.LH, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.LW, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.LBU, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.LHU, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.LOAD, riscv_instr_group_t.RV32I, g=globals())
+# STORE instructions
+DEFINE_INSTR(riscv_instr_name_t.SB, riscv_instr_format_t.S_FORMAT,
+ riscv_instr_category_t.STORE, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SH, riscv_instr_format_t.S_FORMAT,
+ riscv_instr_category_t.STORE, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SW, riscv_instr_format_t.S_FORMAT,
+ riscv_instr_category_t.STORE, riscv_instr_group_t.RV32I, g=globals())
+# SHIFT intructions
+DEFINE_INSTR(riscv_instr_name_t.SLL, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SLLI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SRL, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SRLI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SRA, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SRAI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SHIFT, riscv_instr_group_t.RV32I, g=globals())
+# ARITHMETIC intructions
+DEFINE_INSTR(riscv_instr_name_t.ADD, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.ADDI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.NOP, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SUB, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.LUI, riscv_instr_format_t.U_FORMAT,
+ riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.AUIPC, riscv_instr_format_t.U_FORMAT,
+ riscv_instr_category_t.ARITHMETIC, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
+# LOGICAL instructions
+DEFINE_INSTR(riscv_instr_name_t.XOR, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.XORI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.OR, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.ORI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.AND, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.ANDI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.LOGICAL, riscv_instr_group_t.RV32I, g=globals())
+# COMPARE instructions
+DEFINE_INSTR(riscv_instr_name_t.SLT, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SLTI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SLTU, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SLTIU, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.COMPARE, riscv_instr_group_t.RV32I, g=globals())
+# BRANCH instructions
+DEFINE_INSTR(riscv_instr_name_t.BEQ, riscv_instr_format_t.B_FORMAT,
+ riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.BNE, riscv_instr_format_t.B_FORMAT,
+ riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.BLT, riscv_instr_format_t.B_FORMAT,
+ riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.BGE, riscv_instr_format_t.B_FORMAT,
+ riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.BLTU, riscv_instr_format_t.B_FORMAT,
+ riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.BGEU, riscv_instr_format_t.B_FORMAT,
+ riscv_instr_category_t.BRANCH, riscv_instr_group_t.RV32I, g=globals())
+# JUMP instructions
+DEFINE_INSTR(riscv_instr_name_t.JAL, riscv_instr_format_t.J_FORMAT,
+ riscv_instr_category_t.JUMP, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.JALR, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.JUMP, riscv_instr_group_t.RV32I, g=globals())
+# SYNCH instructions
+DEFINE_INSTR(riscv_instr_name_t.FENCE, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SYNCH, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.FENCE_I, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SYNCH, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SFENCE_VMA, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.SYNCH, riscv_instr_group_t.RV32I, g=globals())
+# SYSTEM instructions
+DEFINE_INSTR(riscv_instr_name_t.ECALL, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.EBREAK, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.URET, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.SRET, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.MRET, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.DRET, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.SYSTEM, riscv_instr_group_t.RV32I, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.WFI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.INTERRUPT, riscv_instr_group_t.RV32I, g=globals())
+# CSR instructions
+DEFINE_INSTR(riscv_instr_name_t.CSRRW, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.CSRRS, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.CSRRC, riscv_instr_format_t.R_FORMAT,
+ riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.CSRRWI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.CSRRSI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
+DEFINE_INSTR(riscv_instr_name_t.CSRRCI, riscv_instr_format_t.I_FORMAT,
+ riscv_instr_category_t.CSR, riscv_instr_group_t.RV32I, imm_t.UIMM, g=globals())
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py
new file mode 100644
index 0000000..d4f2b23
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_defines.py
@@ -0,0 +1,39 @@
+"""
+Copyright 2020 Google LLC
+Copyright 2020 PerfectVIPs Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+Regression script for RISC-V random instruction generator
+
+"""
+
+from pygen_src.riscv_instr_pkg import imm_t
+from pygen_src.isa.riscv_instr import riscv_instr
+
+
+def DEFINE_INSTR(instr_n, instr_format, instr_category, instr_group, imm_tp=imm_t.IMM, g=globals()):
+ class_name = f"riscv_{instr_n.name}_instr"
+
+ def __init__(self):
+ riscv_instr.__init__(self)
+ self.instr_name = instr_n
+ self.format = instr_format
+ self.category = instr_category
+ self.group = instr_group
+ self.imm_type = imm_tp
+
+ self.set_imm_len()
+ self.set_rand_mode()
+ NewClass = type(class_name, (riscv_instr,), {
+ "__init__": __init__,
+ "valid": riscv_instr.register(instr_n)
+ })
+ g[class_name] = NewClass
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py
new file mode 100644
index 0000000..6d59010
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_gen_config.py
@@ -0,0 +1,34 @@
+"""
+Copyright 2020 Google LLC
+Copyright 2020 PerfectVIPs Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+Regression script for RISC-V random instruction generator
+
+"""
+
+
+class riscv_instr_gen_config:
+ def __init__(self):
+ self.enable_floating_point = 1
+ self.disable_compressed_instr = 1
+ self.num_of_test = 3
+ self.no_fence = 1
+ self.enable_sfence = 0
+ self.reserved_regs = []
+ self.enable_illegal_csr_instruction = 0
+ self.enable_access_invalid_csr_level = 0
+ self.invalid_priv_mode_csrs = []
+ self.init_privileged_mode = "MACHINE_MODE"
+ self.no_ebreak = 1
+ self.no_dret = 1
+ self.no_csr_instr = 1
+ self.no_wfi = 1
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_pkg.py b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_pkg.py
new file mode 100644
index 0000000..5edc6a4
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/riscv_instr_pkg.py
@@ -0,0 +1,602 @@
+"""
+Copyright 2020 Google LLC
+Copyright 2020 PerfectVIPs Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+Regression script for RISC-V random instruction generator
+
+"""
+
+from enum import Enum, auto
+
+
+class riscv_instr_name_t(Enum):
+ # RV32I instructions
+ LUI = 0
+ AUIPC = auto()
+ JAL = auto()
+ JALR = auto()
+ BEQ = auto()
+ BNE = auto()
+ BLT = auto()
+ BGE = auto()
+ BLTU = auto()
+ BGEU = auto()
+ LB = auto()
+ LH = auto()
+ LW = auto()
+ LBU = auto()
+ LHU = auto()
+ SB = auto()
+ SH = auto()
+ SW = auto()
+ ADDI = auto()
+ SLTI = auto()
+ SLTIU = auto()
+ XORI = auto()
+ ORI = auto()
+ ANDI = auto()
+ SLLI = auto()
+ SRLI = auto()
+ SRAI = auto()
+ ADD = auto()
+ SUB = auto()
+ SLL = auto()
+ SLT = auto()
+ SLTU = auto()
+ XOR = auto()
+ SRL = auto()
+ SRA = auto()
+ OR = auto()
+ AND = auto()
+ NOP = auto()
+ FENCE = auto()
+ FENCE_I = auto()
+ ECALL = auto()
+ EBREAK = auto()
+ CSRRW = auto()
+ CSRRS = auto()
+ CSRRC = auto()
+ CSRRWI = auto()
+ CSRRSI = auto()
+ CSRRCI = auto()
+ # RV32B instructions
+ ANDN = auto()
+ ORN = auto()
+ XNOR = auto()
+ GORC = auto()
+ SLO = auto()
+ SRO = auto()
+ ROL = auto()
+ ROR = auto()
+ SBCLR = auto()
+ SBSET = auto()
+ SBINV = auto()
+ SBEXT = auto()
+ GREV = auto()
+ SLOI = auto()
+ SROI = auto()
+ RORI = auto()
+ SBCLRI = auto()
+ SBSETI = auto()
+ SBINVI = auto()
+ SBEXTI = auto()
+ GORCI = auto()
+ GREVI = auto()
+ CMIX = auto()
+ CMOV = auto()
+ FSL = auto()
+ FSR = auto()
+ FSRI = auto()
+ CLZ = auto()
+ CTZ = auto()
+ PCNT = auto()
+ SEXT_B = auto()
+ SEXT_H = auto()
+ CRC32_B = auto()
+ CRC32_H = auto()
+ CRC32_W = auto()
+ CRC32C_B = auto()
+ CRC32C_H = auto()
+ CRC32C_W = auto()
+ CLMUL = auto()
+ CLMULR = auto()
+ CLMULH = auto()
+ MIN = auto()
+ MAX = auto()
+ MINU = auto()
+ MAXU = auto()
+ SHFL = auto()
+ UNSHFL = auto()
+ BDEP = auto()
+ BEXT = auto()
+ PACK = auto()
+ PACKU = auto()
+ BMATOR = auto()
+ BMATXOR = auto()
+ PACKH = auto()
+ BFP = auto()
+ SHFLI = auto()
+ UNSHFLI = auto()
+ # RV64B instructions
+ ADDIWU = auto()
+ SLLIU_W = auto()
+ ADDWU = auto()
+ SUBWU = auto()
+ BMATFLIP = auto()
+ CRC32_D = auto()
+ CRC32C_D = auto()
+ ADDU_W = auto()
+ SUBU_W = auto()
+ SLOW = auto()
+ SROW = auto()
+ ROLW = auto()
+ RORW = auto()
+ SBCLRW = auto()
+ SBSETW = auto()
+ SBINVW = auto()
+ SBEXTW = auto()
+ GORCW = auto()
+ GREVW = auto()
+ SLOIW = auto()
+ SROIW = auto()
+ RORIW = auto()
+ SBCLRIW = auto()
+ SBSETIW = auto()
+ SBINVIW = auto()
+ GORCIW = auto()
+ GREVIW = auto()
+ FSLW = auto()
+ FSRW = auto()
+ FSRIW = auto()
+ CLZW = auto()
+ CTZW = auto()
+ PCNTW = auto()
+ CLMULW = auto()
+ CLMULRW = auto()
+ CLMULHW = auto()
+ SHFLW = auto()
+ UNSHFLW = auto()
+ BDEPW = auto()
+ BEXTW = auto()
+ PACKW = auto()
+ PACKUW = auto()
+ BFPW = auto()
+ # RV32M instructions
+ MUL = auto()
+ MULH = auto()
+ MULHSU = auto()
+ MULHU = auto()
+ DIV = auto()
+ DIVU = auto()
+ REM = auto()
+ REMU = auto()
+ # RV64M instructions
+ MULW = auto()
+ DIVW = auto()
+ DIVUW = auto()
+ REMW = auto()
+ REMUW = auto()
+ # RV32F instructions
+ FLW = auto()
+ FSW = auto()
+ FMADD_S = auto()
+ FMSUB_S = auto()
+ FNMSUB_S = auto()
+ FNMADD_S = auto()
+ FADD_S = auto()
+ FSUB_S = auto()
+ FMUL_S = auto()
+ FDIV_S = auto()
+ FSQRT_S = auto()
+ FSGNJ_S = auto()
+ FSGNJN_S = auto()
+ FSGNJX_S = auto()
+ FMIN_S = auto()
+ FMAX_S = auto()
+ FCVT_W_S = auto()
+ FCVT_WU_S = auto()
+ FMV_X_W = auto()
+ FEQ_S = auto()
+ FLT_S = auto()
+ FLE_S = auto()
+ FCLASS_S = auto()
+ FCVT_S_W = auto()
+ FCVT_S_WU = auto()
+ FMV_W_X = auto()
+ # RV64F instruction
+ FCVT_L_S = auto()
+ FCVT_LU_S = auto()
+ FCVT_S_L = auto()
+ FCVT_S_LU = auto()
+ # RV32D instructions
+ FLD = auto()
+ FSD = auto()
+ FMADD_D = auto()
+ FMSUB_D = auto()
+ FNMSUB_D = auto()
+ FNMADD_D = auto()
+ FADD_D = auto()
+ FSUB_D = auto()
+ FMUL_D = auto()
+ FDIV_D = auto()
+ FSQRT_D = auto()
+ FSGNJ_D = auto()
+ FSGNJN_D = auto()
+ FSGNJX_D = auto()
+ FMIN_D = auto()
+ FMAX_D = auto()
+ FCVT_S_D = auto()
+ FCVT_D_S = auto()
+ FEQ_D = auto()
+ FLT_D = auto()
+ FLE_D = auto()
+ FCLASS_D = auto()
+ FCVT_W_D = auto()
+ FCVT_WU_D = auto()
+ FCVT_D_W = auto()
+ FCVT_D_WU = auto()
+ # RV64D
+ FCVT_L_D = auto()
+ FCVT_LU_D = auto()
+ FMV_X_D = auto()
+ FCVT_D_L = auto()
+ FCVT_D_LU = auto()
+ FMV_D_X = auto()
+ # RV64I
+ LWU = auto()
+ LD = auto()
+ SD = auto()
+ ADDIW = auto()
+ SLLIW = auto()
+ SRLIW = auto()
+ SRAIW = auto()
+ ADDW = auto()
+ SUBW = auto()
+ SLLW = auto()
+ SRLW = auto()
+ SRAW = auto()
+ # RV32C
+ C_LW = auto()
+ C_SW = auto()
+ C_LWSP = auto()
+ C_SWSP = auto()
+ C_ADDI4SPN = auto()
+ C_ADDI = auto()
+ C_LI = auto()
+ C_ADDI16SP = auto()
+ C_LUI = auto()
+ C_SRLI = auto()
+ C_SRAI = auto()
+ C_ANDI = auto()
+ C_SUB = auto()
+ C_XOR = auto()
+ C_OR = auto()
+ C_AND = auto()
+ C_BEQZ = auto()
+ C_BNEZ = auto()
+ C_SLLI = auto()
+ C_MV = auto()
+ C_EBREAK = auto()
+ C_ADD = auto()
+ C_NOP = auto()
+ C_J = auto()
+ C_JAL = auto()
+ C_JR = auto()
+ C_JALR = auto()
+ # RV64C
+ C_ADDIW = auto()
+ C_SUBW = auto()
+ C_ADDW = auto()
+ C_LD = auto()
+ C_SD = auto()
+ C_LDSP = auto()
+ C_SDSP = auto()
+ # RV128C
+ C_SRLI64 = auto()
+ C_SRAI64 = auto()
+ C_SLLI64 = auto()
+ C_LQ = auto()
+ C_SQ = auto()
+ C_LQSP = auto()
+ C_SQSP = auto()
+ # RV32FC
+ C_FLW = auto()
+ C_FSW = auto()
+ C_FLWSP = auto()
+ C_FSWSP = auto()
+ # RV32DC
+ C_FLD = auto()
+ C_FSD = auto()
+ C_FLDSP = auto()
+ C_FSDSP = auto()
+ # RV32A
+ LR_W = auto()
+ SC_W = auto()
+ AMOSWAP_W = auto()
+ AMOADD_W = auto()
+ AMOAND_W = auto()
+ AMOOR_W = auto()
+ AMOXOR_W = auto()
+ AMOMIN_W = auto()
+ AMOMAX_W = auto()
+ AMOMINU_W = auto()
+ AMOMAXU_W = auto()
+ # RV64A
+ LR_D = auto()
+ SC_D = auto()
+ AMOSWAP_D = auto()
+ AMOADD_D = auto()
+ AMOAND_D = auto()
+ AMOOR_D = auto()
+ AMOXOR_D = auto()
+ AMOMIN_D = auto()
+ AMOMAX_D = auto()
+ AMOMINU_D = auto()
+ AMOMAXU_D = auto()
+ # Vector instructions
+ VSETVL = auto()
+ VSETVLI = auto()
+ VADD = auto()
+ VSUB = auto()
+ VRSUB = auto()
+ VWADDU = auto()
+ VWSUBU = auto()
+ VWADD = auto()
+ VWSUB = auto()
+ VADC = auto()
+ VMADC = auto()
+ VSBC = auto()
+ VMSBC = auto()
+ VAND = auto()
+ VOR = auto()
+ VXOR = auto()
+ VSLL = auto()
+ VSRL = auto()
+ VSRA = auto()
+ VNSRL = auto()
+ VNSRA = auto()
+ VMSEQ = auto()
+ VMSNE = auto()
+ VMSLTU = auto()
+ VMSLT = auto()
+ VMSLEU = auto()
+ VMSLE = auto()
+ VMSGTU = auto()
+ VMSGT = auto()
+ VMINU = auto()
+ VMIN = auto()
+ VMAXU = auto()
+ VMAX = auto()
+ VMUL = auto()
+ VMULH = auto()
+ VMULHU = auto()
+ VMULHSU = auto()
+ VDIVU = auto()
+ VDIV = auto()
+ VREMU = auto()
+ VREM = auto()
+ VWMUL = auto()
+ VWMULU = auto()
+ VWMULSU = auto()
+ VMACC = auto()
+ VNMSAC = auto()
+ VMADD = auto()
+ VNMSUB = auto()
+ VWMACCU = auto()
+ VWMACC = auto()
+ VWMACCSU = auto()
+ VWMACCUS = auto()
+ '''
+ VQMACCU = auto()
+ VQMACC = auto()
+ VQMACCSU = auto()
+ VQMACCUS = auto()
+ '''
+ VMERGE = auto()
+ VMV = auto()
+ VSADDU = auto()
+ VSADD = auto()
+ VSSUBU = auto()
+ VSSUB = auto()
+ VAADDU = auto()
+ VAADD = auto()
+ VASUBU = auto()
+ VASUB = auto()
+ VSSRL = auto()
+ VSSRA = auto()
+ VNCLIPU = auto()
+ VNCLIP = auto()
+ VFADD = auto()
+ VFSUB = auto()
+ VFRSUB = auto()
+ VFMUL = auto()
+ VFDIV = auto()
+ VFRDIV = auto()
+ VFWMUL = auto()
+ VFMACC = auto()
+ VFNMACC = auto()
+ VFMSAC = auto()
+ VFNMSAC = auto()
+ VFMADD = auto()
+ VFNMADD = auto()
+ VFMSUB = auto()
+ VFNMSUB = auto()
+ VFWMACC = auto()
+ VFWNMACC = auto()
+ VFWMSAC = auto()
+ VFWNMSAC = auto()
+ VFSQRT_V = auto()
+ VFMIN = auto()
+ VFMAX = auto()
+ VFSGNJ = auto()
+ VFSGNJN = auto()
+ VFSGNJX = auto()
+ VMFEQ = auto()
+ VMFNE = auto()
+ VMFLT = auto()
+ VMFLE = auto()
+ VMFGT = auto()
+ VMFGE = auto()
+ VFCLASS_V = auto()
+ VFMERGE = auto()
+ VFMV = auto()
+ VFCVT_XU_F_V = auto()
+ VFCVT_X_F_V = auto()
+ VFCVT_F_XU_V = auto()
+ VFCVT_F_X_V = auto()
+ VFWCVT_XU_F_V = auto()
+ VFWCVT_X_F_V = auto()
+ VFWCVT_F_XU_V = auto()
+ VFWCVT_F_X_V = auto()
+ VFWCVT_F_F_V = auto()
+ VFNCVT_XU_F_W = auto()
+ VFNCVT_X_F_W = auto()
+ VFNCVT_F_XU_W = auto()
+ VFNCVT_F_X_W = auto()
+ VFNCVT_F_F_W = auto()
+ VFNCVT_ROD_F_F_W = auto()
+ # Vector reduction instruction
+ VREDSUM_VS = auto()
+ VREDMAXU_VS = auto()
+ VREDMAX_VS = auto()
+ VREDMINU_VS = auto()
+ VREDMIN_VS = auto()
+ VREDAND_VS = auto()
+ VREDOR_VS = auto()
+ VREDXOR_VS = auto()
+ VWREDSUMU_VS = auto()
+ VWREDSUM_VS = auto()
+ VFREDOSUM_VS = auto()
+ VFREDSUM_VS = auto()
+ VFREDMAX_VS = auto()
+ VFWREDOSUM_VS = auto()
+ VFWREDSUM_VS = auto()
+ # Vector mask instruction
+ VMAND_MM = auto()
+ VMNAND_MM = auto()
+ VMANDNOT_MM = auto()
+ VMXOR_MM = auto()
+ VMOR_MM = auto()
+ VMNOR_MM = auto()
+ VMORNOT_MM = auto()
+ VMXNOR_MM = auto()
+ VPOPC_M = auto()
+ VFIRST_M = auto()
+ VMSBF_M = auto()
+ VMSIF_M = auto()
+ VMSOF_M = auto()
+ VIOTA_M = auto()
+ VID_V = auto()
+ # Vector permutation instruction
+ VMV_X_S = auto()
+ VMV_S_X = auto()
+ VFMV_F_S = auto()
+ VFMV_S_F = auto()
+ VSLIDEUP = auto()
+ VSLIDEDOWN = auto()
+ VSLIDE1UP = auto()
+ VSLIDE1DOWN = auto()
+ VRGATHER = auto()
+ VCOMPRESS = auto()
+ VMV1R_V = auto()
+ VMV2R_V = auto()
+ VMV4R_V = auto()
+ VMV8R_V = auto()
+ # Supervisor instruction
+ DRET = auto()
+ MRET = auto()
+ URET = auto()
+ SRET = auto()
+ WFI = auto()
+ SFENCE_VMA = auto()
+ # Custom instructions
+ # import riscv_custom_instr_enum #TODO: Right now it's not working as expected fix it
+ # You can add other instructions here
+ INVALID_INSTR = auto()
+
+
+class riscv_instr_format_t(Enum):
+ J_FORMAT = 0
+ U_FORMAT = auto()
+ I_FORMAT = auto()
+ B_FORMAT = auto()
+ R_FORMAT = auto()
+ S_FORMAT = auto()
+ R4_FORMAT = auto()
+ # Compressed instruction format
+ CI_FORMAT = auto()
+ CB_FORMAT = auto()
+ CJ_FORMAT = auto()
+ CR_FORMAT = auto()
+ CA_FORMAT = auto()
+ CL_FORMAT = auto()
+ CS_FORMAT = auto()
+ CSS_FORMAT = auto()
+ CIW_FORMAT = auto()
+ # Vector instruction format
+ VSET_FORMAT = auto()
+ VA_FORMAT = auto()
+ VS2_FORMAT = auto() # op vd,vs2
+ VL_FORMAT = auto()
+ VS_FORMAT = auto()
+
+
+class riscv_instr_category_t(Enum):
+ LOAD = 0
+ STORE = auto()
+ SHIFT = auto()
+ ARITHMETIC = auto()
+ LOGICAL = auto()
+ COMPARE = auto()
+ BRANCH = auto()
+ JUMP = auto()
+ SYNCH = auto()
+ SYSTEM = auto()
+ COUNTER = auto()
+ CSR = auto()
+ CHANGELEVEL = auto()
+ TRAP = auto()
+ INTERRUPT = auto()
+ # `VECTOR_INCLUDE("riscv_instr_pkg_inc_riscv_instr_category_t.sv") TODO: Fix this
+ AMO = auto() # (last one)
+
+
+class riscv_instr_group_t(Enum):
+ RV32I = 0
+ RV64I = auto()
+ RV32M = auto()
+ RV64M = auto()
+ RV32A = auto()
+ RV64A = auto()
+ RV32F = auto()
+ RV32FC = auto()
+ RV64F = auto()
+ RV32D = auto()
+ RV32DC = auto()
+ RV64D = auto()
+ RV32C = auto()
+ RV64C = auto()
+ RV128I = auto()
+ RV128C = auto()
+ RV32V = auto()
+ RV32B = auto()
+ RV64V = auto()
+ RV64B = auto()
+ RV32X = auto()
+ RV64X = auto()
+
+
+class imm_t(Enum):
+ IMM = 0 # Signed immediate
+ UIMM = auto() # Unsigned immediate
+ NZUIMM = auto() # Non-zero unsigned immediate
+ NZIMM = auto() # Non-zero signed immediate
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py
new file mode 100644
index 0000000..67bcb6a
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/pygen/pygen_src/test/riscv_instr_base_test.py
@@ -0,0 +1,29 @@
+"""
+Copyright 2020 Google LLC
+Copyright 2020 PerfectVIPs Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+Regression script for RISC-V random instruction generator
+
+"""
+
+import sys
+sys.path.append("../../")
+from pygen_src.isa.rv32i_instr import * # NOQA
+from pygen_src.isa.riscv_instr import cfg, riscv_instr_ins # NOQA
+
+
+class riscv_instr_base_test:
+ def __init__(self):
+ pass
+
+ for _ in range(cfg.num_of_test):
+ riscv_instr_ins.create_instr_list(cfg)
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/requirements.txt b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/requirements.txt
index e616e98..a6b0913 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/requirements.txt
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/requirements.txt
@@ -6,3 +6,4 @@
sphinx-issues
sphinx_rtd_theme
rst2pdf
+flake8
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv
index 35853f0..bcfcf98 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_floating_point_instr.sv
@@ -37,7 +37,7 @@
if (category == LOAD) begin
asm_str = $sformatf("%0s%0s, %0s(%0s)", asm_str, fd.name(), get_imm(), rs1.name());
end else if (instr_name inside {FMV_X_W, FMV_X_D, FCVT_W_S, FCVT_WU_S,
- FCVT_L_S, FCVT_LU_S, FCVT_L_D, FCVT_LU_D, FCVT_LU_S,
+ FCVT_L_S, FCVT_LU_S, FCVT_L_D, FCVT_LU_D,
FCVT_W_D, FCVT_WU_D}) begin
asm_str = $sformatf("%0s%0s, %0s", asm_str, rd.name(), fs1.name());
end else if (instr_name inside {FMV_W_X, FMV_D_X, FCVT_S_W, FCVT_S_WU,
@@ -158,7 +158,9 @@
end
case(format)
I_FORMAT: begin
- `DV_CHECK_FATAL(operands.size() == 2)
+ // TODO ovpsim has an extra operand rte as below
+ // fcvt.d.s fs1,fs4,rte
+ //`DV_CHECK_FATAL(operands.size() == 2)
if (has_fs1) begin
fs1 = get_fpr(operands[1]);
fs1_value = get_gpr_state(operands[1]);
@@ -177,6 +179,13 @@
get_val(operands[1], imm);
end
R_FORMAT: begin
+ // convert Pseudoinstructions for ovpsim
+ // fmv.s rd, rs -> fsgnj.s rd, rs, rs
+ if (operands.size() == 2 && instr_name inside {FSGNJ_S, FSGNJX_S, FSGNJN_S, FSGNJ_D,
+ FSGNJX_D, FSGNJN_D}) begin
+ operands.push_back(operands[$]);
+ end
+
if (has_fs2 || category == CSR) begin
`DV_CHECK_FATAL(operands.size() == 3)
end else begin
@@ -205,7 +214,6 @@
endfunction : update_src_regs
virtual function void update_dst_regs(string reg_name, string val_str);
- $display("update_dst_regs %0s", reg_name);
get_val(val_str, gpr_state[reg_name], .hex(1));
if (has_fd) begin
fd = get_fpr(reg_name);
@@ -218,9 +226,59 @@
virtual function riscv_fpr_t get_fpr(input string str);
str = str.toupper();
- if (!fpr_enum::from_name(str, get_fpr)) begin
+ if (!uvm_enum_wrapper#(riscv_fpr_t)::from_name(str, get_fpr)) begin
`uvm_fatal(`gfn, $sformatf("Cannot convert %0s to FPR", str))
end
endfunction : get_fpr
+ virtual function void pre_sample();
+ super.pre_sample();
+
+ // for single precision sign bit is bit 31, upper 32 bits are all 1s
+ // for double precision, it's 63
+ if (group inside {RV32F, RV64F}) begin
+ fs1_sign = get_fp_operand_sign(fs1_value, 31);
+ fs2_sign = get_fp_operand_sign(fs2_value, 31);
+ fs3_sign = get_fp_operand_sign(fs2_value, 31);
+ fd_sign = get_fp_operand_sign(fd_value, 31);
+ end else if (instr_name == FCVT_S_D) begin
+ fs1_sign = get_fp_operand_sign(fs1_value, 63);
+ fd_sign = get_fp_operand_sign(fd_value, 31);
+ end else if (instr_name == FCVT_D_S) begin
+ fs1_sign = get_fp_operand_sign(fs1_value, 31);
+ fd_sign = get_fp_operand_sign(fd_value, 63);
+ end else begin
+ fs1_sign = get_fp_operand_sign(fs1_value, 63);
+ fs2_sign = get_fp_operand_sign(fs2_value, 63);
+ fs3_sign = get_fp_operand_sign(fs2_value, 63);
+ fd_sign = get_fp_operand_sign(fd_value, 63);
+ end
+ endfunction : pre_sample
+
+ virtual function operand_sign_e get_fp_operand_sign(bit [XLEN-1:0] value, int idx);
+ if (value[idx]) begin
+ return NEGATIVE;
+ end else begin
+ return POSITIVE;
+ end
+ endfunction
+
+ virtual function void check_hazard_condition(riscv_instr pre_instr);
+ riscv_floating_point_instr pre_fp_instr;
+ super.check_hazard_condition(pre_instr);
+ if ($cast(pre_fp_instr, pre_instr) && pre_fp_instr.has_fd) begin
+ if ((has_fs1 && (fs1 == pre_fp_instr.fd)) || (has_fs2 && (fs2 == pre_fp_instr.fd))
+ || (has_fs3 && (fs3 == pre_fp_instr.fd))) begin
+ gpr_hazard = RAW_HAZARD;
+ end else if (has_fd && (fd == pre_fp_instr.fd)) begin
+ gpr_hazard = WAW_HAZARD;
+ end else if (has_fd && ((pre_fp_instr.has_fs1 && (pre_fp_instr.fs1 == fd)) ||
+ (pre_fp_instr.has_fs2 && (pre_fp_instr.fs2 == fd)) ||
+ (pre_fp_instr.has_fs3 && (pre_fp_instr.fs3 == fd)))) begin
+ gpr_hazard = WAR_HAZARD;
+ end else begin
+ gpr_hazard = NO_HAZARD;
+ end
+ end
+ endfunction
endclass
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_instr.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_instr.sv
index 087884e..88e1325 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_instr.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_instr.sv
@@ -32,6 +32,8 @@
static privileged_reg_t exclude_reg[];
static privileged_reg_t include_reg[];
+ riscv_instr_gen_config m_cfg;
+
// Instruction attributes
riscv_instr_group_t group;
riscv_instr_format_t format;
@@ -124,7 +126,9 @@
!(cfg.disable_compressed_instr &&
(instr_inst.group inside {RV32C, RV64C, RV32DC, RV32FC, RV128C})) &&
!(!cfg.enable_floating_point &&
- (instr_inst.group inside {RV32F, RV64F, RV32D, RV64D}))
+ (instr_inst.group inside {RV32F, RV64F, RV32D, RV64D})) &&
+ !(!cfg.enable_vector_extension &&
+ (instr_inst.group inside {RVV}))
) begin
instr_category[instr_inst.category].push_back(instr_name);
instr_group[instr_inst.group].push_back(instr_name);
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_instr_cov.svh b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_instr_cov.svh
index e828f81..18b7925 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_instr_cov.svh
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_instr_cov.svh
@@ -260,10 +260,6 @@
gpr_hazard.name(), lsu_hazard.name()), UVM_FULL)
endfunction
- virtual function void sample_cov();
- pre_sample();
- endfunction
-
virtual function void update_src_regs(string operands[$]);
privileged_reg_t preg;
case(format)
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv
index 5fc70b4..f76f53c 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/riscv_vector_instr.sv
@@ -1,5 +1,6 @@
/*
* Copyright 2020 Google LLC
+ * Copyright 2020 Andes Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,6 +15,8 @@
* limitations under the License.
*/
+
+// Base class for RISC-V vector exenstion ISA, implmented based on spec v0.8
class riscv_vector_instr extends riscv_floating_point_instr;
rand riscv_vreg_t vs1;
@@ -21,14 +24,17 @@
rand riscv_vreg_t vs3;
rand riscv_vreg_t vd;
rand va_variant_t va_variant;
+ rand bit vm;
+ rand bit wd;
bit has_vd = 1'b1;
bit has_vs1 = 1'b1;
bit has_vs2 = 1'b1;
bit has_vs3 = 1'b1;
bit has_vm = 1'b0;
bit has_va_variant;
- bit is_widen_instr;
+ bit is_widening_instr;
bit is_narrowing_instr;
+ bit is_quad_widening_instr;
bit is_convert_instr;
va_variant_t allowed_va_variants[$];
@@ -38,34 +44,132 @@
}
}
- // TODO: Handle different LMUL setting
- // The destination vector register group cannot overlap a source vector
- // register group of a different element width
- constraint widen_instr_c {
- int'(vd) % 2 == 0;
- if (has_vs1) {
- vs1 != vd;
- vs1 != vd + 1;
- }
- if (has_vs2) {
- vs2 != vd;
- vs2 != vd + 1;
+ // Section 3.3.2: Vector Register Grouping (vlmul)
+ // Instructions specifying a vector operand with an odd-numbered vector register will raisean
+ // illegal instruction exception.
+ // TODO: Exclude the instruction that ignore VLMUL
+ constraint operand_group_c {
+ if (m_cfg.vector_cfg.vtype.vlmul > 0) {
+ vd % m_cfg.vector_cfg.vtype.vlmul == 0;
+ vs1 % m_cfg.vector_cfg.vtype.vlmul == 0;
+ vs2 % m_cfg.vector_cfg.vtype.vlmul == 0;
+ vs3 % m_cfg.vector_cfg.vtype.vlmul == 0;
}
}
- // rs2 is double-width source register
- // The destination vector register group cannot overlap the rst source
- // vector register group (specied by vs2)
+ // Section 11.2: Widening Vector Arithmetic Instructions
+ constraint widening_instr_c {
+ if (is_widening_instr) {
+ // The destination vector register group results are arranged as if both
+ // SEW and LMUL were at twice their current settings.
+ vd % (m_cfg.vector_cfg.vtype.vlmul * 2) == 0;
+ // The destination vector register group cannot overlap a source vector
+ // register group of a different element width (including the mask register if masked)
+ !(vs1 inside {[vd : vd + m_cfg.vector_cfg.vtype.vlmul * 2 - 1]});
+ !(vs2 inside {[vd : vd + m_cfg.vector_cfg.vtype.vlmul * 2 - 1]});
+ (vm == 0) -> (vd != 0);
+ // Double-width result, first source double-width, second source single-width
+ if (va_variant inside {WV, WX}) {
+ vs2 % (m_cfg.vector_cfg.vtype.vlmul * 2) == 0;
+ }
+ }
+ }
+
+ // Section 11.3: Narrowing Vector Arithmetic Instructions
constraint narrowing_instr_c {
- if (has_vs2) {
- int'(vs2) % 2 == 0;
- vd != vs2;
- vd != vs2 + 1;
+ if (is_narrowing_instr) {
+ // The source and destination vector register numbers must be aligned
+ // appropriately for the vector registergroup size
+ vs2 % (m_cfg.vector_cfg.vtype.vlmul * 2) == 0;
+ // The destination vector register group cannot overlap the rst source
+ // vector register group (specied by vs2)
+ !(vd inside {[vs2 : vs2 + m_cfg.vector_cfg.vtype.vlmul * 2 - 1]});
+ // The destination vector register group cannot overlap the mask register
+ // if used, unless LMUL=1 (implemented in vmask_overlap_c)
}
}
- // The source and destination vector register numbers must be aligned
- // appropriately for the vector registergroup size
+ // 12.3. Vector Integer Add-with-Carry / Subtract-with-Borrow Instructions
+ constraint add_sub_with_carry_c {
+ if (m_cfg.vector_cfg.vtype.vlmul > 1) {
+ // For vadc and vsbc, an illegal instruction exception is raised if the
+ // destination vector register is v0 and LMUL> 1
+ if (instr_name inside {VADC, VSBC}) {
+ vd != 0;
+ }
+ // For vmadc and vmsbc, an illegal instruction exception is raised if the
+ // destination vector register overlaps asource vector register group and LMUL > 1
+ if (instr_name inside {VMADC, VMSBC}) {
+ vd != vs2;
+ vd != vs1;
+ }
+ }
+ }
+
+ // 12.7. Vector Integer Comparison Instructions
+ // For all comparison instructions, an illegal instruction exception is raised if the
+ // destination vector register overlaps a source vector register group and LMUL > 1
+ constraint compare_instr_c {
+ if (category == COMPARE) {
+ vd != vs2;
+ vd != vs1;
+ }
+ }
+
+ // 16.8. Vector Iota Instruction
+ // An illegal instruction exception is raised if the destination vector register group
+ // overlaps the source vector mask register. If the instruction is masked, an illegal
+ // instruction exception is issued if the destination vector register group overlaps v0.
+ constraint vector_itoa_c {
+ if (instr_name == VIOTA_M) {
+ vd != vs2;
+ (vm == 0) -> (vd != 0);
+ }
+ }
+
+ // 16.9. Vector Element Index Instruction
+ // The vs2 eld of the instruction must be set to v0, otherwise the encoding is reserved
+ constraint vector_element_index_c {
+ if (instr_name == VID_V) {
+ vs2 == 0;
+ // TODO; Check if this constraint is needed
+ vd != vs2;
+ }
+ }
+
+ // Section 17.3 Vector Slide Instructions
+ // The destination vector register group for vslideup cannot overlap the vector register
+ // group of the source vector register group or the mask register
+ constraint vector_slide_c {
+ if (instr_name inside {VSLIDEUP, VSLIDE1UP, VSLIDEDOWN, VSLIDE1DOWN}) {
+ vd != vs2;
+ vd != vs1;
+ (vm == 0) -> (vd != 0);
+ }
+ }
+
+ // Section 17.4: Vector Register Gather Instruction
+ // For any vrgather instruction, the destination vector register group cannot overlap
+ // with the source vector register group
+ constraint vector_gather_c {
+ if (instr_name == VRGATHER) {
+ vd != vs2;
+ vd != vs1;
+ (vm == 0) -> (vd != 0);
+ }
+ }
+
+ // Section 17.5: Vector compress instruction
+ // The destination vector register group cannot overlap the source vector register
+ // group or the source vector mask register
+ constraint vector_compress_c {
+ if (instr_name == VCOMPRESS) {
+ vd != vs2;
+ vd != vs1;
+ (vm == 0) -> (vd != 0);
+ }
+ }
+
constraint vmv_alignment_c {
if (instr_name == VMV2R_V) {
int'(vs2) % 2 == 0;
@@ -81,9 +185,86 @@
}
}
+ /////////////////// Vector mask constraint ///////////////////
+
+ // Section 5.3
+ // The destination vector register group for a masked vector instruction can only overlap
+ // the source mask register (v0) when LMUL=1
+ constraint vmask_overlap_c {
+ (vm == 0) && (m_cfg.vector_cfg.vtype.vlmul > 1) -> (vd != 0);
+ }
+
+ constraint vector_mask_enable_c {
+ // Below instruction is always masked
+ if (instr_name inside {VMERGE, VFMERGE, VADC, VSBC}) {
+ vm == 1'b0;
+ }
+ }
+
+ constraint vector_mask_disable_c {
+ // (vm=0) is reserved for below ops
+ if (instr_name inside {VMV, VFMV, VCOMPRESS, VFMV_F_S, VFMV_S_F, VMV_X_S, VMV_S_X,
+ VMV1R_V, VMV2R_V, VMV4R_V, VMV8R_V}) {
+ vm == 1'b1;
+ }
+ }
+
+ // 16.1. Vector Mask-Register Logical Instructions
+ // No vector mask for these instructions
+ constraint vector_mask_instr_c {
+ if (instr_name inside {[VMAND_MM : VMXNOR_MM]}) {
+ vm == 1'b1;
+ }
+ }
+
+ constraint disable_floating_point_varaint_c {
+ if (!m_cfg.vector_cfg.vec_fp) {
+ va_variant != VF;
+ }
+ }
+
+ // TODO: Check why this is needed?
+ constraint vector_load_store_mask_overlap_c {
+ if (category == STORE) {
+ (vm == 0) -> (vs3 != 0);
+ }
+ }
+
`uvm_object_utils(riscv_vector_instr)
`uvm_object_new
+ // Filter unsupported instructions based on configuration
+ virtual function bit is_supported(riscv_instr_gen_config cfg);
+ string name = instr_name.name();
+ // 19.2.2. Vector Add with Carry/Subtract with Borrow Reserved under EDIV>1
+ if ((cfg.vector_cfg.vtype.vediv > 1) &&
+ (instr_name inside {VADC, VSBC, VMADC, VMSBC})) begin
+ return 1'b0;
+ end
+ // Disable widening/narrowing instruction when LMUL == 8
+ if ((!cfg.vector_cfg.vec_narrowing_widening) &&
+ (is_widening_instr || is_narrowing_instr)) begin
+ return 1'b0;
+ end
+ if (!cfg.vector_cfg.vec_quad_widening && is_quad_widening_instr) begin
+ return 1'b0;
+ end
+ // TODO: Clean up this list, it's causing gcc compile error now
+ if (instr_name inside {VWMACCSU, VMERGE, VFMERGE, VMADC, VMSBC}) begin
+ return 1'b0;
+ end
+ // The standard vector floating-point instructions treat 16-bit, 32-bit, 64-bit,
+ // and 128-bit elements as IEEE-754/2008-compatible values. If the current SEW does
+ // not correspond to a supported IEEE floating-pointtype, an illegal instruction
+ // exception is raised
+ if (!cfg.vector_cfg.vec_fp) begin
+ if ((name.substr(0, 1) == "VF") || (name.substr(0, 2) == "VMF")) begin
+ return 1'b0;
+ end
+ end
+ return 1'b1;
+ endfunction
+
// Convert the instruction to assembly code
virtual function string convert2asm(string prefix = "");
string asm_str;
@@ -148,17 +329,32 @@
end
endcase
end
- if (instr_name inside {VMADC, VADC, VSBC, VMSBC, VMERGE, VFMERGE}) begin
- if (va_variant inside {VVM, VIM, VXM, VFM}) begin
- asm_str = {asm_str, ",v0"};
- end
- end else begin
- //asm_str = {asm_str, ",v0.t"};
- end
end
end
- default: `uvm_info(`gfn, $sformatf("Unsupported format %0s", format.name()), UVM_LOW)
+ VL_FORMAT: begin
+ asm_str = $sformatf("%0s %s,(%s)", get_instr_name(), vd.name(), rs1.name());
+ end
+ VS_FORMAT: begin
+ asm_str = $sformatf("%0s %s,(%s)", get_instr_name(), vs3.name(), rs1.name());
+ end
+ VLS_FORMAT: begin
+ asm_str = $sformatf("%0s %0s,(%0s),%0s", get_instr_name(), vd.name(), rs1.name(), rs2.name());
+ end
+ VSS_FORMAT: begin
+ asm_str = $sformatf("%0s %0s,(%0s),%0s", get_instr_name(), vs3.name(), rs1.name(), rs2.name());
+ end
+ VLV_FORMAT: begin
+ asm_str = $sformatf("%0s,%0s,(%0s),%0s", get_instr_name(), vd.name(), rs1.name(), vs2.name());
+ end
+ VSV_FORMAT: begin
+ asm_str = $sformatf("%0s,%0s,(%0s),%0s", get_instr_name(), vs3.name(), rs1.name(), vs2.name());
+ end
+ default: begin
+ `uvm_fatal(`gfn, $sformatf("Unsupported format %0s", format.name()))
+ end
endcase
+ // Add vector mask
+ asm_str = {asm_str, vec_vm_str()};
if(comment != "") begin
asm_str = {asm_str, " #",comment};
end
@@ -183,10 +379,14 @@
has_fs3 = 0;
has_fd = 0;
has_imm = 0;
- if (name.substr(0, 1) == "VW") begin
- is_widen_instr = 1'b1;
+ if ((name.substr(0, 1) == "VW") || (name.substr(0, 2) == "VFW")) begin
+ is_widening_instr = 1'b1;
end
- if (name.substr(0, 1) == "VN") begin
+ if (name.substr(0, 2) == "VQW") begin
+ is_quad_widening_instr = 1'b1;
+ is_widening_instr = 1'b1;
+ end
+ if ((name.substr(0, 1) == "VN") || (name.substr(0, 2) == "VFN")) begin
is_narrowing_instr = 1'b1;
end
if (uvm_is_match("*CVT*", name)) begin
@@ -204,4 +404,16 @@
end
endfunction : set_rand_mode
+ virtual function string vec_vm_str();
+ if (vm) begin
+ return "";
+ end else begin
+ if (instr_name inside {VMERGE, VFMERGE, VADC, VSBC, VMADC, VMSBC}) begin
+ return ",v0";
+ end else begin
+ return ",v0.t";
+ end
+ end
+ endfunction
+
endclass : riscv_vector_instr
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/rv32v_instr.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/rv32v_instr.sv
index 9198417..2a3eb7e 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/rv32v_instr.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/isa/rv32v_instr.sv
@@ -1,5 +1,6 @@
/*
* Copyright 2020 Google LLC
+ * Copyright 2020 Andes Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,185 +16,237 @@
*/
// Vector CSR access instruction
-`DEFINE_INSTR(VSETVLI, VSET_FORMAT, CSR, RV32V)
-`DEFINE_INSTR(VSETVL, VSET_FORMAT, CSR, RV32V)
+`DEFINE_INSTR(VSETVLI, VSET_FORMAT, CSR, RVV)
+`DEFINE_INSTR(VSETVL, VSET_FORMAT, CSR, RVV)
// Vector integer arithmetic instruction
-`DEFINE_VA_INSTR(VADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VRSUB, VA_FORMAT, ARITHMETIC, RV32V, {VX, VI})
-`DEFINE_VA_INSTR(VWADDU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, WV, WX})
-`DEFINE_VA_INSTR(VWSUBU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, WV, WX})
-`DEFINE_VA_INSTR(VWADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, WV, WX})
-`DEFINE_VA_INSTR(VWSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, WV, WX})
-`DEFINE_VA_INSTR(VADC, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM, VIM})
-`DEFINE_VA_INSTR(VMADC, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM, VIM, VV, VX, VI})
-`DEFINE_VA_INSTR(VSBC, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM})
-`DEFINE_VA_INSTR(VMSBC, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM, VV, VX})
-`DEFINE_VA_INSTR(VAND, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VOR, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VXOR, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VSLL, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VSRL, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VSRA, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VNSRL, VA_FORMAT, SHIFT, RV32V, {WV, WX, WI})
-`DEFINE_VA_INSTR(VNSRA, VA_FORMAT, SHIFT, RV32V, {WV, WX, WI})
-`DEFINE_VA_INSTR(VMSEQ, VA_FORMAT, COMPARE, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VMSNE, VA_FORMAT, COMPARE, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VMSLTU, VA_FORMAT, COMPARE, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMSLT, VA_FORMAT, COMPARE, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMSLEU, VA_FORMAT, COMPARE, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VMSLE, VA_FORMAT, COMPARE, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VMSGTU, VA_FORMAT, COMPARE, RV32V, {VX, VI})
-`DEFINE_VA_INSTR(VMSGT, VA_FORMAT, COMPARE, RV32V, {VX, VI})
-`DEFINE_VA_INSTR(VMINU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMIN, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMAXU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMAX, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMUL, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMULH, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMULHU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMULHSU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VDIVU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VDIV, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VREMU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VREM, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VWMUL, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VWMULU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VWMULSU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VNMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VMADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VNMSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VWMACCU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VWMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VWMACCSU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VWMACCUS, VA_FORMAT, ARITHMETIC, RV32V, {VX})
-/*
-`DEFINE_VA_INSTR(VQMACCU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VQMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VQMACCSU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VQMACCUS, VA_FORMAT, ARITHMETIC, RV32V, {VX})
+`DEFINE_VA_INSTR(VADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VRSUB, VA_FORMAT, ARITHMETIC, RVV, {VX, VI})
+`DEFINE_VA_INSTR(VWADDU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, WV, WX})
+`DEFINE_VA_INSTR(VWSUBU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, WV, WX})
+`DEFINE_VA_INSTR(VWADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, WV, WX})
+`DEFINE_VA_INSTR(VWSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, WV, WX})
+`DEFINE_VA_INSTR(VADC, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM, VIM})
+`DEFINE_VA_INSTR(VMADC, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM, VIM, VV, VX, VI})
+`DEFINE_VA_INSTR(VSBC, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM})
+`DEFINE_VA_INSTR(VMSBC, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM, VV, VX})
+`DEFINE_VA_INSTR(VAND, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VOR, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VXOR, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VSLL, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VSRL, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VSRA, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VNSRL, VA_FORMAT, SHIFT, RVV, {WV, WX, WI})
+`DEFINE_VA_INSTR(VNSRA, VA_FORMAT, SHIFT, RVV, {WV, WX, WI})
+`DEFINE_VA_INSTR(VMSEQ, VA_FORMAT, COMPARE, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VMSNE, VA_FORMAT, COMPARE, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VMSLTU, VA_FORMAT, COMPARE, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMSLT, VA_FORMAT, COMPARE, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMSLEU, VA_FORMAT, COMPARE, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VMSLE, VA_FORMAT, COMPARE, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VMSGTU, VA_FORMAT, COMPARE, RVV, {VX, VI})
+`DEFINE_VA_INSTR(VMSGT, VA_FORMAT, COMPARE, RVV, {VX, VI})
+`DEFINE_VA_INSTR(VMINU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMIN, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMAXU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMAX, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMUL, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMULH, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMULHU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMULHSU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VDIVU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VDIV, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VREMU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VREM, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VWMUL, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VWMULU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VWMULSU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VNMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VMADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VNMSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VWMACCU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VWMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VWMACCSU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VWMACCUS, VA_FORMAT, ARITHMETIC, RVV, {VX})
+/* Quad widening is not yet supported
+`DEFINE_VA_INSTR(VQMACCU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VQMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VQMACCSU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VQMACCUS, VA_FORMAT, ARITHMETIC, RVV, {VX})
*/
-`DEFINE_VA_INSTR(VMERGE, VA_FORMAT, ARITHMETIC, RV32V, {VVM, VXM, VIM})
-`DEFINE_VA_INSTR(VMV, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
+`DEFINE_VA_INSTR(VMERGE, VA_FORMAT, ARITHMETIC, RVV, {VVM, VXM, VIM})
+`DEFINE_VA_INSTR(VMV, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
// Vector Fixed-Point Arithmetic Instructions
-`DEFINE_VA_INSTR(VSADDU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VSADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VSSUBU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VSSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VAADDU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VAADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VASUBU, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VASUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VX})
-`DEFINE_VA_INSTR(VSSRL, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VSSRA, VA_FORMAT, SHIFT, RV32V, {VV, VX, VI})
-`DEFINE_VA_INSTR(VNCLIPU, VA_FORMAT, ARITHMETIC, RV32V, {WV, WX, WI})
-`DEFINE_VA_INSTR(VNCLIP, VA_FORMAT, ARITHMETIC, RV32V, {WV, WX, WI})
+`DEFINE_VA_INSTR(VSADDU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VSADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VSSUBU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VSSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VAADDU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VAADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VASUBU, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VASUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VX})
+`DEFINE_VA_INSTR(VSSRL, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VSSRA, VA_FORMAT, SHIFT, RVV, {VV, VX, VI})
+`DEFINE_VA_INSTR(VNCLIPU, VA_FORMAT, ARITHMETIC, RVV, {WV, WX, WI})
+`DEFINE_VA_INSTR(VNCLIP, VA_FORMAT, ARITHMETIC, RVV, {WV, WX, WI})
// Vector Floating-Point Instructions
-`DEFINE_VA_INSTR(VFADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFRSUB, VA_FORMAT, ARITHMETIC, RV32V, {VF})
-`DEFINE_VA_INSTR(VFMUL, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFDIV, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFRDIV, VA_FORMAT, ARITHMETIC, RV32V, {VF})
-`DEFINE_VA_INSTR(VFWMUL, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFNMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFNMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFMADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFNMADD, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFMSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFNMSUB, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFWMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFWNMACC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFWMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFWNMSAC, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFSQRT_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFMIN, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFMAX, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFSGNJ, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFSGNJN, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VFSGNJX, VA_FORMAT, ARITHMETIC, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VMFEQ, VA_FORMAT, COMPARE, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VMFNE, VA_FORMAT, COMPARE, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VMFLT, VA_FORMAT, COMPARE, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VMFLE, VA_FORMAT, COMPARE, RV32V, {VV, VF})
-`DEFINE_VA_INSTR(VMFGT, VA_FORMAT, COMPARE, RV32V, {VF})
-`DEFINE_VA_INSTR(VMFGE, VA_FORMAT, COMPARE, RV32V, {VF})
-`DEFINE_VA_INSTR(VFCLASS_V,VS2_FORMAT, COMPARE, RV32V)
-`DEFINE_VA_INSTR(VFMERGE, VA_FORMAT, ARITHMETIC, RV32V, {VFM})
-`DEFINE_VA_INSTR(VFMV, VA_FORMAT, ARITHMETIC, RV32V, {VF})
+`DEFINE_VA_INSTR(VFADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFRSUB, VA_FORMAT, ARITHMETIC, RVV, {VF})
+`DEFINE_VA_INSTR(VFMUL, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFDIV, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFRDIV, VA_FORMAT, ARITHMETIC, RVV, {VF})
+`DEFINE_VA_INSTR(VFWMUL, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFNMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFNMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFMADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFNMADD, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFMSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFNMSUB, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFWMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFWNMACC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFWMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFWNMSAC, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFSQRT_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFMIN, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFMAX, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFSGNJ, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFSGNJN, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VFSGNJX, VA_FORMAT, ARITHMETIC, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VMFEQ, VA_FORMAT, COMPARE, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VMFNE, VA_FORMAT, COMPARE, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VMFLT, VA_FORMAT, COMPARE, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VMFLE, VA_FORMAT, COMPARE, RVV, {VV, VF})
+`DEFINE_VA_INSTR(VMFGT, VA_FORMAT, COMPARE, RVV, {VF})
+`DEFINE_VA_INSTR(VMFGE, VA_FORMAT, COMPARE, RVV, {VF})
+`DEFINE_VA_INSTR(VFCLASS_V,VS2_FORMAT, COMPARE, RVV)
+`DEFINE_VA_INSTR(VFMERGE, VA_FORMAT, ARITHMETIC, RVV, {VFM})
+`DEFINE_VA_INSTR(VFMV, VA_FORMAT, ARITHMETIC, RVV, {VF})
// Vector conversion instructions
-`DEFINE_VA_INSTR(VFCVT_XU_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFCVT_X_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFCVT_F_XU_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFCVT_F_X_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFWCVT_XU_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFWCVT_X_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFWCVT_F_XU_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFWCVT_F_X_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFWCVT_F_F_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFNCVT_XU_F_W, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFNCVT_X_F_W, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFNCVT_F_XU_W, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFNCVT_F_X_W, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFNCVT_F_F_W, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFNCVT_ROD_F_F_W, VS2_FORMAT, ARITHMETIC, RV32V)
+`DEFINE_VA_INSTR(VFCVT_XU_F_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFCVT_X_F_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFCVT_F_XU_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFCVT_F_X_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFWCVT_XU_F_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFWCVT_X_F_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFWCVT_F_XU_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFWCVT_F_X_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFWCVT_F_F_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFNCVT_XU_F_W, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFNCVT_X_F_W, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFNCVT_F_XU_W, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFNCVT_F_X_W, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFNCVT_F_F_W, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFNCVT_ROD_F_F_W, VS2_FORMAT, ARITHMETIC, RVV)
// Vector reduction instruction
-`DEFINE_VA_INSTR(VREDSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VREDMAXU_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VREDMAX_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VREDMINU_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VREDMIN_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VREDAND_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VREDOR_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VREDXOR_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VWREDSUMU_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VWREDSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFREDOSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFREDSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFREDMAX_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFWREDOSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFWREDSUM_VS, VA_FORMAT, ARITHMETIC, RV32V)
+`DEFINE_VA_INSTR(VREDSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VREDMAXU_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VREDMAX_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VREDMINU_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VREDMIN_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VREDAND_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VREDOR_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VREDXOR_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VWREDSUMU_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VWREDSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFREDOSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFREDSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFREDMAX_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFWREDOSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFWREDSUM_VS, VA_FORMAT, ARITHMETIC, RVV)
// Vector mask instruction
-`DEFINE_VA_INSTR(VMAND_MM, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMNAND_MM, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMANDNOT_MM, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMXOR_MM, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMOR_MM, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMNOR_MM, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMORNOT_MM, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMXNOR_MM, VA_FORMAT, ARITHMETIC, RV32V)
+`DEFINE_VA_INSTR(VMAND_MM, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMNAND_MM, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMANDNOT_MM, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMXOR_MM, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMOR_MM, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMNOR_MM, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMORNOT_MM, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMXNOR_MM, VA_FORMAT, ARITHMETIC, RVV)
-`DEFINE_VA_INSTR(VPOPC_M, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFIRST_M, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMSBF_M, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMSIF_M, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMSOF_M, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VIOTA_M, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VID_V, VS2_FORMAT, ARITHMETIC, RV32V)
+`DEFINE_VA_INSTR(VPOPC_M, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFIRST_M, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMSBF_M, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMSIF_M, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMSOF_M, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VIOTA_M, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VID_V, VS2_FORMAT, ARITHMETIC, RVV)
// Vector permutation instruction
-`DEFINE_VA_INSTR(VMV_X_S, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMV_S_X, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFMV_F_S, VA_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VFMV_S_F, VA_FORMAT, ARITHMETIC, RV32V)
+`DEFINE_VA_INSTR(VMV_X_S, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMV_S_X, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFMV_F_S, VA_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VFMV_S_F, VA_FORMAT, ARITHMETIC, RVV)
-`DEFINE_VA_INSTR(VSLIDEUP, VA_FORMAT, ARITHMETIC, RV32V, {VI,VX})
-`DEFINE_VA_INSTR(VSLIDEDOWN, VA_FORMAT, ARITHMETIC, RV32V, {VI,VX})
-`DEFINE_VA_INSTR(VSLIDE1UP, VA_FORMAT, ARITHMETIC, RV32V, {VX})
-`DEFINE_VA_INSTR(VSLIDE1DOWN, VA_FORMAT, ARITHMETIC, RV32V, {VX})
-`DEFINE_VA_INSTR(VRGATHER, VA_FORMAT, ARITHMETIC, RV32V, {VV,VX,VI})
-`DEFINE_VA_INSTR(VCOMPRESS, VA_FORMAT, ARITHMETIC, RV32V, {VM})
+`DEFINE_VA_INSTR(VSLIDEUP, VA_FORMAT, ARITHMETIC, RVV, {VI,VX})
+`DEFINE_VA_INSTR(VSLIDEDOWN, VA_FORMAT, ARITHMETIC, RVV, {VI,VX})
+`DEFINE_VA_INSTR(VSLIDE1UP, VA_FORMAT, ARITHMETIC, RVV, {VX})
+`DEFINE_VA_INSTR(VSLIDE1DOWN, VA_FORMAT, ARITHMETIC, RVV, {VX})
+`DEFINE_VA_INSTR(VRGATHER, VA_FORMAT, ARITHMETIC, RVV, {VV,VX,VI})
+`DEFINE_VA_INSTR(VCOMPRESS, VA_FORMAT, ARITHMETIC, RVV, {VM})
-`DEFINE_VA_INSTR(VMV1R_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMV2R_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMV4R_V, VS2_FORMAT, ARITHMETIC, RV32V)
-`DEFINE_VA_INSTR(VMV8R_V, VS2_FORMAT, ARITHMETIC, RV32V)
+`DEFINE_VA_INSTR(VMV1R_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMV2R_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMV4R_V, VS2_FORMAT, ARITHMETIC, RVV)
+`DEFINE_VA_INSTR(VMV8R_V, VS2_FORMAT, ARITHMETIC, RVV)
+
+// -------------------------------------------------------------------------
+// Section 7. Vector Loads and Stores
+// -------------------------------------------------------------------------
+// Section 7.4 - Vector Unit-Stride Instructions
+`DEFINE_VA_INSTR(VLE_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VSE_V, VS_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VLB_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VSB_V, VS_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VLH_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VSH_V, VS_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VLW_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VSW_V, VS_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VLBU_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLHU_V, VS_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLWU_V, VL_FORMAT, LOAD, RVV)
+// Section 7.5 - Vector Strided Instructions
+`DEFINE_VA_INSTR(VLSB_V, VLS_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLSH_V, VLS_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLSW_V, VLS_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLSBU_V, VLS_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLSHU_V, VLS_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLSWU_V, VLS_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLSE_V, VLS_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VSSB_V, VSS_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSSH_V, VSS_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSSW_V, VSS_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSSE_V, VSS_FORMAT, STORE, RVV)
+// Section 7.6 - Vector Indexed Instructions
+`DEFINE_VA_INSTR(VLXB_V, VLV_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLXH_V, VLV_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLXW_V, VLV_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLXBU_V, VLV_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLXHU_V, VLV_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLXWU_V, VLV_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLXE_V, VLV_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VSXB_V, VSV_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSXH_V, VSV_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSXW_V, VSV_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSXE_V, VSV_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSUXB_V, VSV_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSUXH_V, VSV_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSUXW_V, VSV_FORMAT, STORE, RVV)
+`DEFINE_VA_INSTR(VSUXE_V, VSV_FORMAT, STORE, RVV)
+// Section 7.7 - Vector Unit-Stride Fault-Only-First Loads
+`DEFINE_VA_INSTR(VLBFF_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLHFF_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLWFF_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLBUFF_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLHUFF_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLWUFF_V, VL_FORMAT, LOAD, RVV)
+`DEFINE_VA_INSTR(VLEFF_V, VL_FORMAT, LOAD, RVV)
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
index 96d3cad..d9a4876 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_asm_program_gen.sv
@@ -1,5 +1,6 @@
/*
* Copyright 2018 Google LLC
+ * Copyright 2020 Andes Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -78,7 +79,7 @@
gen_init_section(hart);
// If PMP is supported, we want to generate the associated trap handlers and the test_done
// section at the start of the program so we can allow access through the pmpcfg0 CSR
- if (support_pmp && !cfg.bare_program_mode) begin
+ if (riscv_instr_pkg::support_pmp && !cfg.bare_program_mode) begin
gen_trap_handlers(hart);
// Ecall handler
gen_ecall_handler(hart);
@@ -119,7 +120,7 @@
instr_stream = {instr_stream, $sformatf("%sj test_done", indent)};
// Test done section
// If PMP isn't supported, generate this in the normal location
- if (hart == 0 & !support_pmp) begin
+ if (hart == 0 & !riscv_instr_pkg::support_pmp) begin
gen_test_done();
end
// Shuffle the sub programs and insert to the instruction stream
@@ -320,7 +321,8 @@
if (cfg.disable_compressed_instr) begin
instr_stream.push_back(".option norvc;");
end
- str = {"csrr x5, mhartid"};
+ str.push_back(".include \"user_init.s\"");
+ str.push_back("csrr x5, mhartid");
for (int hart = 0; hart < cfg.num_of_harts; hart++) begin
str = {str, $sformatf("li x6, %0d", hart),
$sformatf("beq x5, x6, %0df", hart)};
@@ -411,19 +413,19 @@
string str;
str = format_string(get_label("init:", hart), LABEL_STR_LEN);
instr_stream.push_back(str);
+ if (cfg.enable_floating_point) begin
+ init_floating_point_gpr();
+ end
init_gpr();
// Init stack pointer to point to the end of the user stack
str = {indent, $sformatf("la x%0d, %0suser_stack_end", cfg.sp, hart_prefix(hart))};
instr_stream.push_back(str);
- if (cfg.enable_floating_point) begin
- init_floating_point_gpr();
- end
if (cfg.enable_vector_extension) begin
- init_vector_engine();
+ randomize_vec_gpr_and_csr();
end
core_is_initialized();
gen_dummy_csr_write(); // TODO add a way to disable xStatus read
- if (support_pmp) begin
+ if (riscv_instr_pkg::support_pmp) begin
str = {indent, "j main"};
instr_stream.push_back(str);
end
@@ -446,7 +448,7 @@
RV32B, RV64B : misa[MISA_EXT_B] = 1'b1;
RV32F, RV64F, RV32FC : misa[MISA_EXT_F] = 1'b1;
RV32D, RV64D, RV32DC : misa[MISA_EXT_D] = 1'b1;
- RV32V, RV64V : misa[MISA_EXT_V] = 1'b1;
+ RVV : misa[MISA_EXT_V] = 1'b1;
RV32X, RV64X : misa[MISA_EXT_X] = 1'b1;
default : `uvm_fatal(`gfn, $sformatf("%0s is not yet supported",
supported_isa[i].name()))
@@ -515,7 +517,7 @@
string str;
bit [DATA_WIDTH-1:0] reg_val;
// Init general purpose registers with random values
- for(int i = 0; i < 32; i++) begin
+ for(int i = 0; i < NUM_GPR; i++) begin
if (i inside {cfg.sp, cfg.tp}) continue;
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(reg_val,
reg_val dist {
@@ -530,38 +532,132 @@
end
endfunction
+ // Initialize vector general purpose registers
+ virtual function void init_vec_gpr();
+ int SEW;
+ int LMUL;
+ int EDIV = 1;
+ int len = (ELEN <= XLEN) ? ELEN : XLEN;
+ int num_elements = VLEN / len;
+ if (!(RVV inside {supported_isa})) return;
+ LMUL = 1;
+ SEW = (ELEN <= XLEN) ? ELEN : XLEN;
+ instr_stream.push_back($sformatf("li x%0d, %0d", cfg.gpr[1], cfg.vector_cfg.vl));
+ // vec registers will be loaded from a scalar GPR, one element at a time
+ instr_stream.push_back($sformatf("%svsetvli x%0d, x%0d, e%0d, m%0d, d%0d",
+ indent, cfg.gpr[0], cfg.gpr[1], SEW, LMUL, EDIV));
+ instr_stream.push_back("vec_reg_init:");
+ for (int v = 1; v < NUM_VEC_GPR; v++) begin
+ for (int e = 0; e < num_elements; e++) begin
+ if (e > 0) instr_stream.push_back($sformatf("%0svmv.v.v v0, v%0d", indent, v));
+ instr_stream.push_back($sformatf("%0sli x%0d, 0x%0x",
+ indent, cfg.gpr[0], $urandom_range(0, 2 ** SEW - 1)));
+ instr_stream.push_back($sformatf("%0svslide1up.vx v%0d, v0, t0", indent, v));
+ end
+ end
+ endfunction
+
// Initialize floating point general purpose registers
virtual function void init_floating_point_gpr();
int int_gpr;
string str;
- // TODO: Initialize floating point GPR with more interesting numbers
- for(int i = 0; i < 32; i++) begin
- int_gpr = $urandom_range(0, 31);
- // Use a random integer GPR to initialize floating point GPR
- if (RV64F inside {supported_isa}) begin
- str = $sformatf("%0sfcvt.d.l f%0d, x%0d", indent, i, int_gpr);
- end else begin
- str = $sformatf("%0sfcvt.s.w f%0d, x%0d", indent, i, int_gpr);
- end
- instr_stream.push_back(str);
+ for(int i = 0; i < NUM_FLOAT_GPR; i++) begin
+ randcase
+ 1: init_floating_point_gpr_with_spf(i);
+ RV64D inside {supported_isa}: init_floating_point_gpr_with_dpf(i);
+ endcase
end
// Initialize rounding mode of FCSR
str = $sformatf("%0sfsrmi %0d", indent, cfg.fcsr_rm);
instr_stream.push_back(str);
endfunction
- // Initialize vector registers
- virtual function void init_vector_engine();
- string str[$];
- // Initialize vtype, vl
- str = {str, $sformatf("li x%0d, %0d", cfg.gpr[1], cfg.vector_cfg.vl),
- $sformatf("vsetvli x%0d, x%0d, e%0d",
- cfg.gpr[0], cfg.gpr[1], 8 * (2 ** cfg.vector_cfg.vtype.vsew))};
- for(int i = 0; i < 32; i++) begin
- // Use integer register to initialize vector register
- str = {str, $sformatf("vmv.v.x v%0d, x%0d", i, i)};
+ // get instructions initialize floating_point_gpr with single precision floating value
+ virtual function void init_floating_point_gpr_with_spf(int int_floating_gpr);
+ string str;
+ bit [31:0] imm = get_rand_spf_value();
+ int int_gpr = $urandom_range(0, NUM_GPR - 1);
+
+ str = $sformatf("%0sli x%0d, %0d", indent, int_gpr, imm);
+ instr_stream.push_back(str);
+ str = $sformatf("%0sfmv.w.x f%0d, x%0d", indent, int_floating_gpr, int_gpr);
+ instr_stream.push_back(str);
+ endfunction
+
+ // get instructions initialize floating_point_gpr with double precision floating value
+ virtual function void init_floating_point_gpr_with_dpf(int int_floating_gpr);
+ string str;
+ bit [63:0] imm = get_rand_dpf_value();
+ int int_gpr1 = $urandom_range(1, NUM_GPR - 1);
+ int int_gpr2 = $urandom_range(1, NUM_GPR - 1);
+
+ str = $sformatf("%0sli x%0d, %0d", indent, int_gpr1, imm[63:32]);
+ instr_stream.push_back(str);
+ // shift to upper 32bits
+ repeat (2) begin
+ str = $sformatf("%0sslli x%0d, x%0d, 16", indent, int_gpr1, int_gpr1);
+ instr_stream.push_back(str);
end
- instr_stream = {instr_stream, str};
+ str = $sformatf("%0sli x%0d, %0d", indent, int_gpr2, imm[31:0]);
+ instr_stream.push_back(str);
+ str = $sformatf("%0sor x%0d, x%0d, x%0d", indent, int_gpr2, int_gpr2, int_gpr1);
+ instr_stream.push_back(str);
+ str = $sformatf("%0sfmv.d.x f%0d, x%0d", indent, int_floating_gpr, int_gpr2);
+ instr_stream.push_back(str);
+ endfunction
+
+ // get a random single precision floating value
+ virtual function bit [XLEN-1:0] get_rand_spf_value();
+ bit [31:0] value;
+
+ randcase
+ // infinity
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value inside {32'h7f80_0000, 32'hff80_0000};)
+ // largest
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value inside {32'h7f7f_ffff, 32'hff7f_ffff};)
+ // zero
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value inside {32'h0000_0000, 32'h8000_0000};)
+ // NaN
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value inside {32'h7f80_0001, 32'h7fc0_0000};)
+ // normal
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value[30:SINGLE_PRECISION_FRACTION_BITS] > 0;)
+ // subnormal
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value[30:SINGLE_PRECISION_FRACTION_BITS] == 0;)
+ endcase
+ return value;
+ endfunction
+
+ // get a random double precision floating value
+ virtual function bit [XLEN-1:0] get_rand_dpf_value();
+ bit [63:0] value;
+
+ randcase
+ // infinity
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value inside {64'h7ff0_0000_0000_0000, 64'hfff0_0000_0000_0000};)
+ // largest
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value inside {64'h7fef_ffff_ffff_ffff, 64'hffef_ffff_ffff_ffff};)
+ // zero
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value inside {64'h0000_0000_0000_0000, 64'h8000_0000_0000_0000};)
+ // NaN
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value inside {64'h7ff0_0000_0000_0001, 64'h7ff8_0000_0000_0000};)
+ // normal
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value[62:DOUBLE_PRECISION_FRACTION_BITS] > 0;)
+ // subnormal
+ 1: `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(value,
+ value[62:DOUBLE_PRECISION_FRACTION_BITS] == 0;)
+ endcase
+ return value;
endfunction
// Generate "test_done" section, test is finished by an ECALL instruction
@@ -795,7 +891,7 @@
virtual function void gen_all_trap_handler(int hart);
string instr[$];
// If PMP isn't supported, generate the relevant trap handler sections as per usual
- if (!support_pmp) begin
+ if (!riscv_instr_pkg::support_pmp) begin
gen_trap_handlers(hart);
// Ecall handler
gen_ecall_handler(hart);
@@ -1450,4 +1546,25 @@
instr_stream = {instr_stream, debug_rom.instr_stream};
endfunction
+ //---------------------------------------------------------------------------------------
+ // Vector extension generation
+ //---------------------------------------------------------------------------------------
+
+ virtual function void randomize_vec_gpr_and_csr();
+ if (!(RVV inside {supported_isa})) return;
+ instr_stream.push_back({indent, $sformatf("li x%0d, %0d", cfg.gpr[0], cfg.vector_cfg.vxsat)});
+ instr_stream.push_back({indent, $sformatf("csrw vxsat, x%0d", cfg.gpr[0])});
+ instr_stream.push_back({indent, $sformatf("li x%0d, %0d", cfg.gpr[0], cfg.vector_cfg.vxrm)});
+ instr_stream.push_back({indent, $sformatf("csrw vxrm, x%0d", cfg.gpr[0])});
+ init_vec_gpr(); // GPR init uses a temporary SEW/LMUL setting before the final value set below.
+ instr_stream.push_back($sformatf("li x%0d, %0d", cfg.gpr[1], cfg.vector_cfg.vl));
+ instr_stream.push_back($sformatf("%svsetvli x%0d, x%0d, e%0d, m%0d, d%0d",
+ indent,
+ cfg.gpr[0],
+ cfg.gpr[1],
+ cfg.vector_cfg.vtype.vsew,
+ cfg.vector_cfg.vtype.vlmul,
+ cfg.vector_cfg.vtype.vediv));
+ endfunction
+
endclass
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv
index 3dfba5d..f3bc708 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_directed_instr_lib.sv
@@ -192,9 +192,9 @@
instr_list[i].atomic = 1'b1;
end
jump.has_label = 1'b1;
- jump.label = "1";
+ jump.label = $sformatf("%0s_j%0d", label, idx);
jump.comment = $sformatf("jump %0s -> %0s", label, target_program_label);
- branch.imm_str = "1f";
+ branch.imm_str = jump.label;
branch.comment = "branch to jump instr";
branch.branch_assigned = 1'b1;
endfunction
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv
index 9c016e6..33896ad 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_cover_group.sv
@@ -228,17 +228,62 @@
`INSTR_CG_BEGIN(INSTR_NAME) \
cp_imm_sign : coverpoint instr.imm_sign;
-// TODO, will handle special value later
-// single-precision floating point special values coverpoint
-`define FP_SPECIAL_VALUES_CP(VAR, NAME) \
- cp_fp_special_values_on_``NAME`` : coverpoint VAR { \
+// single/double precision floating point special values coverpoint
+`define FP_SPECIAL_VALUES_CP(VAR, NAME, PRECISION = S) \
+ cp_sfp_special_values_on_``NAME`` : coverpoint VAR[31:0] { \
+ option.weight = (`"PRECISION`" == "S"); \
+ type_option.weight = (`"PRECISION`" == "S"); \
bins infinity[] = {32'h7f80_0000, 32'hff80_0000}; \
bins largest[] = {32'h7f7f_ffff, 32'hff7f_ffff}; \
- bins zeros[] = {32'h0000_0000, 32'h1000_0000}; \
- bins NaN[] = {32'h7fc0_0000, 32'h7f80_0000}; \
+ bins zeros[] = {32'h0000_0000, 32'h8000_0000}; \
+ bins NaN[] = {32'h7f80_0001, 32'h7fc0_0000}; \
+ } \
+ cp_sfp_subnormal_on_``NAME`` : coverpoint VAR[30:SINGLE_PRECISION_FRACTION_BITS] == 0 { \
+ option.weight = (`"PRECISION`" == "S"); \
+ type_option.weight = (`"PRECISION`" == "S"); \
+ } \
+ cp_dfp_special_values_on_``NAME`` : coverpoint VAR { \
+ option.weight = (`"PRECISION`" == "D"); \
+ type_option.weight = (`"PRECISION`" == "D"); \
+ bins infinity[] = {64'h7ff0_0000_0000_0000, 64'hfff0_0000_0000_0000}; \
+ bins largest[] = {64'h7fef_ffff_ffff_ffff, 64'hffef_ffff_ffff_ffff}; \
+ bins zeros[] = {64'h0000_0000_0000_0000, 64'h8000_0000_0000_0000}; \
+ bins NaN[] = {64'h7ff0_0000_0000_0001, 64'h7ff8_0000_0000_0000}; \
+ } \
+ cp_dfp_subnormal_on_``NAME`` : coverpoint VAR[62:DOUBLE_PRECISION_FRACTION_BITS-1] == 0 { \
+ option.weight = (`"PRECISION`" == "D"); \
+ type_option.weight = (`"PRECISION`" == "D"); \
}
-`define FP_R_INSTR_CG_BEGIN(INSTR_NAME) \
+`define FP_LOAD_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
+ `INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
+ cp_rs1 : coverpoint instr.rs1 { \
+ `DV(ignore_bins zero = {ZERO};) \
+ } \
+ cp_fd : coverpoint instr.fd; \
+ cp_imm_sign : coverpoint instr.imm_sign; \
+ `FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, PRECISION) \
+ `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
+ `DV(cp_lsu_hazard : coverpoint instr.lsu_hazard { \
+ bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
+ })
+
+`define FP_STORE_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
+ `INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
+ cp_rs1 : coverpoint instr.rs1 { \
+ `DV(ignore_bins zero = {ZERO};) \
+ } \
+ cp_fs2 : coverpoint instr.fs2; \
+ cp_imm_sign : coverpoint instr.imm_sign; \
+ `FP_SPECIAL_VALUES_CP(instr.fs2_value, fs2_value, PRECISION) \
+ `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard { \
+ bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD}; \
+ }) \
+ `DV(cp_lsu_hazard : coverpoint instr.lsu_hazard { \
+ bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD}; \
+ })
+
+`define FP_R_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
cp_fs1 : coverpoint instr.fs1; \
cp_fs2 : coverpoint instr.fs2; \
@@ -246,9 +291,12 @@
cp_fs1_sign : coverpoint instr.fs1_sign; \
cp_fs2_sign : coverpoint instr.fs2_sign; \
cp_fd_sign : coverpoint instr.fd_sign; \
+ `FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
+ `FP_SPECIAL_VALUES_CP(instr.fs2_value, fs2_value, PRECISION) \
+ `FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, PRECISION) \
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
-`define FP_R4_INSTR_CG_BEGIN(INSTR_NAME) \
+`define FP_R4_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
cp_fs1 : coverpoint instr.fs1; \
cp_fs2 : coverpoint instr.fs2; \
@@ -259,14 +307,74 @@
cp_fs3_sign : coverpoint instr.fs3_sign; \
cp_fd_sign : coverpoint instr.fd_sign; \
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fs3_sign, cp_fd_sign; \
+ `FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
+ `FP_SPECIAL_VALUES_CP(instr.fs2_value, fs2_value, PRECISION) \
+ `FP_SPECIAL_VALUES_CP(instr.fs3_value, fs3_value, PRECISION) \
+ `FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, PRECISION) \
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
-`define FSQRT_INSTR_CG_BEGIN(INSTR_NAME) \
+`define FSQRT_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
`INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
cp_fs1 : coverpoint instr.fs1; \
cp_fd : coverpoint instr.fd; \
cp_fs1_sign : coverpoint instr.fs1_sign; \
cp_fd_sign : coverpoint instr.fd_sign; \
+ `FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
+ `FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, PRECISION) \
+ `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
+
+// FCVT integer to floating
+`define FP_I2F_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S, SIGN_TYP = SIGN) \
+ `INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
+ cp_rs1 : coverpoint instr.rs1; \
+ cp_fd : coverpoint instr.fd; \
+ cp_rs1_sign : coverpoint instr.rs1_sign { \
+ option.weight = (`"SIGN_TYP`" == "SIGN"); \
+ type_option.weight = (`"SIGN_TYP`" == "SIGN"); \
+ } \
+ cp_fd_sign : coverpoint instr.fd_sign { \
+ option.weight = (`"SIGN_TYP`" == "SIGN"); \
+ type_option.weight = (`"SIGN_TYP`" == "SIGN"); \
+ } \
+ `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
+
+// FCVT floating to integer
+`define FP_F2I_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S, SIGN_TYP = SIGN) \
+ `INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
+ cp_fs1 : coverpoint instr.fs1; \
+ cp_rd : coverpoint instr.rd; \
+ cp_fs1_sign : coverpoint instr.fs1_sign; \
+ cp_rd_sign : coverpoint instr.rd_sign { \
+ option.weight = (`"SIGN_TYP`" == "SIGN"); \
+ type_option.weight = (`"SIGN_TYP`" == "SIGN"); \
+ } \
+ `FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
+ `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
+
+// floating compare instructions
+`define FP_CMP_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
+ `INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
+ cp_fs1 : coverpoint instr.fs1; \
+ cp_fs2 : coverpoint instr.fs2; \
+ cp_rd : coverpoint instr.rd; \
+ cp_fs1_sign : coverpoint instr.fs1_sign; \
+ cp_fs2_sign : coverpoint instr.fs2_sign; \
+ `CP_VALUE_RANGE(compare_result, instr.rd_value, 0, 1) \
+ `FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
+ `FP_SPECIAL_VALUES_CP(instr.fs2_value, fs2_value, PRECISION) \
+ `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
+
+`define FCLASS_INSTR_CG_BEGIN(INSTR_NAME, PRECISION = S) \
+ `INSTR_CG_BEGIN(INSTR_NAME, riscv_floating_point_instr) \
+ cp_fs1 : coverpoint instr.fs1; \
+ cp_rd : coverpoint instr.rd; \
+ cp_fs1_sign : coverpoint instr.fs1_sign; \
+ cp_rd_value : coverpoint instr.rd_value { \
+ bins values[] = {0, 'b1, 'b10, 'b100, 'b1000, 'b1_0000, 'b10_0000, \
+ 'b100_0000, 'b1000_0000, 'b1_0000_0000, 'b10_0000_0000}; \
+ illegal_bins others = default; \
+ } \
+ `FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, PRECISION) \
`DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;) \
`define B_I_INSTR_CG_BEGIN(INSTR_NAME) \
@@ -317,7 +425,6 @@
class riscv_instr_cover_group;
riscv_instr_gen_config cfg;
- riscv_instr cur_instr;
riscv_instr pre_instr;
riscv_instr_name_t instr_list[$];
int unsigned instr_cnt;
@@ -537,72 +644,219 @@
`CG_END
// floating instructions
- `INSTR_CG_BEGIN(flw, riscv_floating_point_instr)
- cp_rs1 : coverpoint instr.rs1 {
- `DV(ignore_bins zero = {ZERO};)
- }
- cp_fd : coverpoint instr.fd;
- cp_imm_sign : coverpoint instr.imm_sign;
- `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;)
- `DV(cp_lsu_hazard : coverpoint instr.lsu_hazard {
- bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD};
- })
+ `FP_LOAD_INSTR_CG_BEGIN(flw)
`CG_END
- `INSTR_CG_BEGIN(fsw, riscv_floating_point_instr)
- cp_rs1 : coverpoint instr.rs1 {
- `DV(ignore_bins zero = {ZERO};)
- }
- cp_fs2 : coverpoint instr.fs2;
- cp_imm_sign : coverpoint instr.imm_sign;
- `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard {
- bins valid_hazard[] = {NO_HAZARD, RAW_HAZARD};
- })
- `DV(cp_lsu_hazard : coverpoint instr.lsu_hazard {
- bins valid_hazard[] = {NO_HAZARD, WAR_HAZARD, WAW_HAZARD};
- })
+ `FP_LOAD_INSTR_CG_BEGIN(fld, D)
+ `CG_END
+
+ `FP_STORE_INSTR_CG_BEGIN(fsw)
+ `CG_END
+
+ `FP_STORE_INSTR_CG_BEGIN(fsd, D)
`CG_END
`FP_R_INSTR_CG_BEGIN(fadd_s)
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign;
`CG_END
+ `FP_R_INSTR_CG_BEGIN(fadd_d, D)
+ cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign;
+ `CG_END
+
`FP_R_INSTR_CG_BEGIN(fsub_s)
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign;
`CG_END
+ `FP_R_INSTR_CG_BEGIN(fsub_d, D)
+ cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign, cp_fd_sign;
+ `CG_END
+
`FP_R_INSTR_CG_BEGIN(fmul_s)
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
`CG_END
+ `FP_R_INSTR_CG_BEGIN(fmul_d, D)
+ cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
+ `CG_END
+
`FP_R_INSTR_CG_BEGIN(fdiv_s)
- cp_div_result: coverpoint instr.div_result;
+ cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
+ `CG_END
+
+ `FP_R_INSTR_CG_BEGIN(fdiv_d, D)
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
`CG_END
`FSQRT_INSTR_CG_BEGIN(fsqrt_s)
`CG_END
+ `FSQRT_INSTR_CG_BEGIN(fsqrt_d, D)
+ `CG_END
+
`FP_R_INSTR_CG_BEGIN(fmin_s)
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
`CG_END
+ `FP_R_INSTR_CG_BEGIN(fmin_d, D)
+ cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
+ `CG_END
+
`FP_R_INSTR_CG_BEGIN(fmax_s)
cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
`CG_END
+ `FP_R_INSTR_CG_BEGIN(fmax_d, D)
+ cp_sign_cross: cross cp_fs1_sign, cp_fs2_sign;
+ `CG_END
+
`FP_R4_INSTR_CG_BEGIN(fmadd_s)
`CG_END
+ `FP_R4_INSTR_CG_BEGIN(fmadd_d, D)
+ `CG_END
+
`FP_R4_INSTR_CG_BEGIN(fnmadd_s)
`CG_END
+ `FP_R4_INSTR_CG_BEGIN(fnmadd_d, D)
+ `CG_END
+
`FP_R4_INSTR_CG_BEGIN(fmsub_s)
`CG_END
+ `FP_R4_INSTR_CG_BEGIN(fmsub_d, D)
+ `CG_END
+
`FP_R4_INSTR_CG_BEGIN(fnmsub_s)
`CG_END
+ `FP_R4_INSTR_CG_BEGIN(fnmsub_d, D)
+ `CG_END
+
+ // FCVT floating to floating
+ `INSTR_CG_BEGIN(fcvt_s_d, riscv_floating_point_instr)
+ cp_fs1 : coverpoint instr.fs1;
+ cp_fd : coverpoint instr.fd;
+ cp_fs1_sign : coverpoint instr.fs1_sign;
+ cp_fd_sign : coverpoint instr.fd_sign;
+ `FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, D)
+ `FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, S)
+ `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;)
+ `CG_END
+
+ `INSTR_CG_BEGIN(fcvt_d_s, riscv_floating_point_instr)
+ cp_fs1 : coverpoint instr.fs1;
+ cp_fd : coverpoint instr.fd;
+ cp_fs1_sign : coverpoint instr.fs1_sign;
+ cp_fd_sign : coverpoint instr.fd_sign;
+ `FP_SPECIAL_VALUES_CP(instr.fs1_value, fs1_value, S)
+ `FP_SPECIAL_VALUES_CP(instr.fd_value, fd_value, D)
+ `DV(cp_gpr_hazard : coverpoint instr.gpr_hazard;)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fcvt_w_s)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fcvt_wu_s, , UNSIGN)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fcvt_l_s)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fcvt_lu_s, UNSIGN)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fcvt_l_d, D)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fcvt_lu_d, D, UNSIGN)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fcvt_w_d, D)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fcvt_wu_d, D, UNSIGN)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fcvt_s_w)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fcvt_s_wu, , UNSIGN)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fcvt_s_l)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fcvt_d_l, D)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fcvt_s_lu, , UNSIGN)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fcvt_d_w, D)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fcvt_d_lu, D, UNSIGN)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fcvt_d_wu, D, UNSIGN)
+ `CG_END
+
+ `FP_R_INSTR_CG_BEGIN(fsgnj_s)
+ `CG_END
+
+ `FP_R_INSTR_CG_BEGIN(fsgnj_d, D)
+ `CG_END
+
+ `FP_R_INSTR_CG_BEGIN(fsgnjn_s)
+ `CG_END
+
+ `FP_R_INSTR_CG_BEGIN(fsgnjn_d, D)
+ `CG_END
+
+ `FP_R_INSTR_CG_BEGIN(fsgnjx_s)
+ `CG_END
+
+ `FP_R_INSTR_CG_BEGIN(fsgnjx_d, D)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fmv_x_w)
+ `CG_END
+
+ `FP_F2I_INSTR_CG_BEGIN(fmv_x_d, D)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fmv_w_x)
+ `CG_END
+
+ `FP_I2F_INSTR_CG_BEGIN(fmv_d_x, D)
+ `CG_END
+
+ `FP_CMP_INSTR_CG_BEGIN(feq_s)
+ `CG_END
+
+ `FP_CMP_INSTR_CG_BEGIN(feq_d, D)
+ `CG_END
+
+ `FP_CMP_INSTR_CG_BEGIN(flt_s)
+ `CG_END
+
+ `FP_CMP_INSTR_CG_BEGIN(flt_d, D)
+ `CG_END
+
+ `FP_CMP_INSTR_CG_BEGIN(fle_s)
+ `CG_END
+
+ `FP_CMP_INSTR_CG_BEGIN(fle_d, D)
+ `CG_END
+
+ `FCLASS_INSTR_CG_BEGIN(fclass_s)
+ `CG_END
+
+ `FCLASS_INSTR_CG_BEGIN(fclass_d, D)
+ `CG_END
+
// B extension
// Count Leading/Trailing Zeros (clz, ctz)
`B_R_INSTR_NO_RS2_CG_BEGIN(clz)
@@ -1462,8 +1716,6 @@
function new(riscv_instr_gen_config cfg);
string opts;
this.cfg = cfg;
- cur_instr = riscv_instr::type_id::create("cur_instr");
- pre_instr = riscv_instr::type_id::create("pre_instr");
build_instr_list();
`ifdef COMPLIANCE_MODE
compliance_mode = 1;
@@ -1659,6 +1911,64 @@
fnmadd_s_cg = new();
fmsub_s_cg = new();
fnmsub_s_cg = new();
+ fcvt_w_s_cg = new();
+ fcvt_wu_s_cg = new();
+ fcvt_s_w_cg = new();
+ fcvt_s_wu_cg = new();
+ fsgnj_s_cg = new();
+ fsgnjn_s_cg = new();
+ fsgnjx_s_cg = new();
+ fmv_x_w_cg = new();
+ fmv_w_x_cg = new();
+ feq_s_cg = new();
+ flt_s_cg = new();
+ fle_s_cg = new();
+ fclass_s_cg = new();
+ `CG_SELECTOR_END
+
+ `CG_SELECTOR_BEGIN(RV32D)
+ fld_cg = new();
+ fsd_cg = new();
+ fadd_d_cg = new();
+ fsub_d_cg = new();
+ fdiv_d_cg = new();
+ fmul_d_cg = new();
+ fmadd_d_cg = new();
+ fnmadd_d_cg = new();
+ fmsub_d_cg = new();
+ fnmsub_d_cg = new();
+ fsqrt_d_cg = new();
+ fmin_d_cg = new();
+ fmax_d_cg = new();
+ fsgnj_d_cg = new();
+ fsgnjn_d_cg = new();
+ fsgnjx_d_cg = new();
+ feq_d_cg = new();
+ flt_d_cg = new();
+ fle_d_cg = new();
+ fcvt_w_d_cg = new();
+ fcvt_wu_d_cg = new();
+ fcvt_d_w_cg = new();
+ fcvt_d_wu_cg = new();
+ fclass_d_cg = new();
+ `CG_SELECTOR_END
+
+ `CG_SELECTOR_BEGIN(RV64F)
+ fcvt_l_s_cg = new();
+ fcvt_lu_s_cg = new();
+ fcvt_s_l_cg = new();
+ fcvt_s_lu_cg = new();
+ `CG_SELECTOR_END
+
+ `CG_SELECTOR_BEGIN(RV64D)
+ fmv_x_d_cg = new();
+ fmv_d_x_cg = new();
+ fcvt_d_s_cg = new();
+ fcvt_s_d_cg = new();
+ fcvt_l_d_cg = new();
+ fcvt_lu_d_cg = new();
+ fcvt_d_l_cg = new();
+ fcvt_d_lu_cg = new();
`CG_SELECTOR_END
`CG_SELECTOR_BEGIN(RV32B)
@@ -1913,18 +2223,67 @@
C_ADDW : `SAMPLE(c_addw_cg, instr)
C_ADDIW : `SAMPLE(c_addiw_cg, instr)
FLW : `SAMPLE_F(flw_cg, instr)
+ FLD : `SAMPLE_F(fld_cg, instr)
FSW : `SAMPLE_F(fsw_cg, instr)
+ FSD : `SAMPLE_F(fsd_cg, instr)
FADD_S : `SAMPLE_F(fadd_s_cg, instr)
+ FADD_D : `SAMPLE_F(fadd_d_cg, instr)
FSUB_S : `SAMPLE_F(fsub_s_cg, instr)
+ FSUB_D : `SAMPLE_F(fsub_d_cg, instr)
FMUL_S : `SAMPLE_F(fmul_s_cg, instr)
+ FMUL_D : `SAMPLE_F(fmul_d_cg, instr)
FDIV_S : `SAMPLE_F(fdiv_s_cg, instr)
+ FDIV_D : `SAMPLE_F(fdiv_d_cg, instr)
FSQRT_S : `SAMPLE_F(fsqrt_s_cg, instr)
+ FSQRT_D : `SAMPLE_F(fsqrt_d_cg, instr)
FMIN_S : `SAMPLE_F(fmin_s_cg, instr)
+ FMIN_D : `SAMPLE_F(fmin_d_cg, instr)
FMAX_S : `SAMPLE_F(fmax_s_cg, instr)
+ FMAX_D : `SAMPLE_F(fmax_d_cg, instr)
FMADD_S : `SAMPLE_F(fmadd_s_cg, instr)
+ FMADD_D : `SAMPLE_F(fmadd_d_cg, instr)
FNMADD_S : `SAMPLE_F(fnmadd_s_cg, instr)
+ FNMADD_D : `SAMPLE_F(fnmadd_d_cg, instr)
FMSUB_S : `SAMPLE_F(fmsub_s_cg, instr)
+ FMSUB_D : `SAMPLE_F(fmsub_d_cg, instr)
FNMSUB_S : `SAMPLE_F(fnmsub_s_cg, instr)
+ FNMSUB_D : `SAMPLE_F(fnmsub_d_cg, instr)
+ FCVT_W_S : `SAMPLE_F(fcvt_w_s_cg, instr)
+ FCVT_WU_S : `SAMPLE_F(fcvt_wu_s_cg, instr)
+ FCVT_L_S : `SAMPLE_F(fcvt_l_s_cg, instr)
+ FCVT_LU_S : `SAMPLE_F(fcvt_lu_s_cg, instr)
+ FCVT_L_D : `SAMPLE_F(fcvt_l_d_cg, instr)
+ FCVT_LU_D : `SAMPLE_F(fcvt_lu_d_cg, instr)
+ FCVT_S_D : `SAMPLE_F(fcvt_s_d_cg, instr)
+ FCVT_D_S : `SAMPLE_F(fcvt_d_s_cg, instr)
+ FCVT_W_D : `SAMPLE_F(fcvt_w_d_cg, instr)
+ FCVT_WU_D : `SAMPLE_F(fcvt_wu_d_cg, instr)
+ FCVT_S_W : `SAMPLE_F(fcvt_s_w_cg, instr)
+ FCVT_S_WU : `SAMPLE_F(fcvt_s_wu_cg, instr)
+ FCVT_S_L : `SAMPLE_F(fcvt_s_l_cg, instr)
+ FCVT_D_L : `SAMPLE_F(fcvt_d_l_cg, instr)
+ FCVT_S_LU : `SAMPLE_F(fcvt_s_lu_cg, instr)
+ FCVT_D_W : `SAMPLE_F(fcvt_d_w_cg, instr)
+ FCVT_D_LU : `SAMPLE_F(fcvt_d_lu_cg, instr)
+ FCVT_D_WU : `SAMPLE_F(fcvt_d_wu_cg, instr)
+ FSGNJ_S : `SAMPLE_F(fsgnj_s_cg, instr)
+ FSGNJ_D : `SAMPLE_F(fsgnj_d_cg, instr)
+ FSGNJN_S : `SAMPLE_F(fsgnjn_s_cg, instr)
+ FSGNJN_D : `SAMPLE_F(fsgnjn_d_cg, instr)
+ FSGNJX_S : `SAMPLE_F(fsgnjx_s_cg, instr)
+ FSGNJX_D : `SAMPLE_F(fsgnjx_d_cg, instr)
+ FMV_X_W : `SAMPLE_F(fmv_x_w_cg, instr)
+ FMV_X_D : `SAMPLE_F(fmv_x_d_cg, instr)
+ FMV_W_X : `SAMPLE_F(fmv_w_x_cg, instr)
+ FMV_D_X : `SAMPLE_F(fmv_d_x_cg, instr)
+ FEQ_S : `SAMPLE_F(feq_s_cg, instr)
+ FEQ_D : `SAMPLE_F(feq_d_cg, instr)
+ FLT_S : `SAMPLE_F(flt_s_cg, instr)
+ FLT_D : `SAMPLE_F(flt_d_cg, instr)
+ FLE_S : `SAMPLE_F(fle_s_cg, instr)
+ FLE_D : `SAMPLE_F(fle_d_cg, instr)
+ FCLASS_S : `SAMPLE_F(fclass_s_cg, instr)
+ FCLASS_D : `SAMPLE_F(fclass_d_cg, instr)
// RV32B
CLZ : `SAMPLE_B(clz_cg, instr)
CTZ : `SAMPLE_B(ctz_cg, instr)
@@ -2068,8 +2427,7 @@
end
end
`VECTOR_INCLUDE("riscv_instr_cover_group_inc_sample.sv")
- pre_instr.copy(instr);
- pre_instr.mem_addr = instr.mem_addr;
+ pre_instr = instr;
endfunction
// Check if the instruction is supported
@@ -2096,11 +2454,12 @@
instr_name = instr_name.first;
do begin
riscv_instr instr;
- if (!(instr_name inside {unsupported_instr}) && (instr_name != INVALID_INSTR)) begin
+ if (!(instr_name inside {unsupported_instr}) && (instr_name != INVALID_INSTR) &&
+ riscv_instr::instr_registry.exists(instr_name)) begin
instr = riscv_instr::create_instr(instr_name);
if ((instr.group inside {supported_isa}) &&
(instr.group inside {RV32I, RV32M, RV64M, RV64I, RV32C, RV64C,
- RV32V, RV64V, RV64B, RV32B})) begin
+ RVV, RV64B, RV32B})) begin
if (((instr_name inside {URET}) && !support_umode_trap) ||
((instr_name inside {SRET, SFENCE_VMA}) &&
!(SUPERVISOR_MODE inside {supported_privileged_mode})) ||
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv
index 5f92aa6..3200353 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_gen_config.sv
@@ -328,6 +328,8 @@
constraint mstatus_c {
if (set_mstatus_mprv) {
mstatus_mprv == 1'b1;
+ } else {
+ mstatus_mprv == 1'b0;
}
if (SATP_MODE == BARE) {
mstatus_mxr == 0;
@@ -591,7 +593,7 @@
get_invalid_priv_lvl_csr();
endfunction
- function void setup_instr_distribution();
+ virtual function void setup_instr_distribution();
string opts;
int val;
get_int_arg_value("+dist_control_mode=", dist_control_mode);
@@ -643,7 +645,7 @@
end
endfunction
- function void get_non_reserved_gpr();
+ virtual function void get_non_reserved_gpr();
endfunction
function void post_randomize();
@@ -659,7 +661,7 @@
end
endfunction
- function void check_setting();
+ virtual function void check_setting();
bit support_64b;
bit support_128b;
foreach (riscv_instr_pkg::supported_isa[i]) begin
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_pkg.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_pkg.sv
index c60dd57..de51c44 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_pkg.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_pkg.sv
@@ -1,5 +1,6 @@
/*
* Copyright 2018 Google LLC
+ * Copyright 2020 Andes Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -89,9 +90,8 @@
RV64C,
RV128I,
RV128C,
- RV32V,
+ RVV,
RV32B,
- RV64V,
RV64B,
RV32X,
RV64X
@@ -474,12 +474,10 @@
VWMACC,
VWMACCSU,
VWMACCUS,
- /*
- VQMACCU,
- VQMACC,
- VQMACCSU,
- VQMACCUS,
- */
+ //VQMACCU,
+ //VQMACC,
+ //VQMACCSU,
+ //VQMACCUS,
VMERGE,
VMV,
VSADDU,
@@ -494,6 +492,7 @@
VSSRA,
VNCLIPU,
VNCLIP,
+ // 14. Vector Floating-Point Instructions
VFADD,
VFSUB,
VFRSUB,
@@ -543,7 +542,7 @@
VFNCVT_F_X_W,
VFNCVT_F_F_W,
VFNCVT_ROD_F_F_W,
- // Vector reduction instruction
+ // 15. Vector reduction instruction
VREDSUM_VS,
VREDMAXU_VS,
VREDMAX_VS,
@@ -590,6 +589,51 @@
VMV2R_V,
VMV4R_V,
VMV8R_V,
+ // Vector load/store instruction
+ VLE_V,
+ VSE_V,
+ VLB_V,
+ VSB_V,
+ VLH_V,
+ VSH_V,
+ VLW_V,
+ VSW_V,
+ VLBU_V,
+ VLHU_V,
+ VLWU_V,
+ VLSB_V,
+ VLSH_V,
+ VLSW_V,
+ VLSBU_V,
+ VLSHU_V,
+ VLSWU_V,
+ VLSE_V,
+ VSSB_V,
+ VSSH_V,
+ VSSW_V,
+ VSSE_V,
+ VLXB_V,
+ VLXH_V,
+ VLXW_V,
+ VLXBU_V,
+ VLXHU_V,
+ VLXWU_V,
+ VLXE_V,
+ VSXB_V,
+ VSXH_V,
+ VSXW_V,
+ VSXE_V,
+ VSUXB_V,
+ VSUXH_V,
+ VSUXW_V,
+ VSUXE_V,
+ VLBFF_V,
+ VLHFF_V,
+ VLWFF_V,
+ VLBUFF_V,
+ VLHUFF_V,
+ VLWUFF_V,
+ VLEFF_V,
// Supervisor instruction
DRET,
MRET,
@@ -606,6 +650,9 @@
// Maximum virtual address bits used by the program
parameter int MAX_USED_VADDR_BITS = 30;
+ parameter int SINGLE_PRECISION_FRACTION_BITS = 23;
+ parameter int DOUBLE_PRECISION_FRACTION_BITS = 52;
+
typedef enum bit [4:0] {
ZERO = 5'b00000,
RA, SP, GP, TP, T0, T1, T2, S0, S1, A0, A1, A2, A3, A4, A5, A6, A7,
@@ -645,7 +692,11 @@
VA_FORMAT,
VS2_FORMAT, // op vd,vs2
VL_FORMAT,
- VS_FORMAT
+ VS_FORMAT,
+ VLV_FORMAT,
+ VSV_FORMAT,
+ VLS_FORMAT,
+ VSS_FORMAT
} riscv_instr_format_t;
@@ -1090,9 +1141,9 @@
typedef struct packed {
bit ill;
bit [XLEN-2:7] reserved;
- bit [1:0] vediv;
- bit [2:0] vsew;
- bit [1:0] vlmul;
+ int vediv;
+ int vsew;
+ int vlmul;
} vtype_t;
typedef enum bit [1:0] {
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_sequence.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_sequence.sv
index e2a22e9..b343608 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_sequence.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_sequence.sv
@@ -275,6 +275,12 @@
str = {prefix, instr_stream.instr_list[i].convert2asm()};
instr_string_list.push_back(str);
end
+ // If PMP is supported, need to align <main> to a 4-byte boundary.
+ // TODO(udi) - this might interfere with multi-hart programs,
+ // may need to specifically match hart0.
+ if (riscv_instr_pkg::support_pmp && !uvm_re_match("*main*", label_name)) begin
+ instr_string_list.push_front(".align 2");
+ end
insert_illegal_hint_instr();
prefix = format_string($sformatf("%0d:", i), LABEL_STR_LEN);
if(!is_main_program) begin
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_stream.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_stream.sv
index ab72deb..0f737e2 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_stream.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_instr_stream.sv
@@ -186,6 +186,18 @@
setup_instruction_dist(no_branch, no_load_store);
endfunction
+ virtual function void randomize_avail_regs();
+ if(avail_regs.size() > 0) begin
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(avail_regs,
+ unique{avail_regs};
+ avail_regs[0] inside {[S0 : A5]};
+ foreach(avail_regs[i]) {
+ !(avail_regs[i] inside {cfg.reserved_regs, reserved_rd});
+ },
+ "Cannot randomize avail_regs")
+ end
+ endfunction
+
function void setup_instruction_dist(bit no_branch = 1'b0, bit no_load_store = 1'b1);
if (cfg.dist_control_mode) begin
category_dist = cfg.category_dist;
@@ -227,6 +239,7 @@
end
instr = riscv_instr::get_rand_instr(.include_instr(allowed_instr),
.exclude_instr(exclude_instr));
+ instr.m_cfg = cfg;
randomize_gpr(instr);
endfunction
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv
index 94c771e..e95e3cc 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_load_store_instr_lib.sv
@@ -1,5 +1,6 @@
/*
* Copyright 2018 Google LLC
+ * Copyright 2020 Andes Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -120,19 +121,11 @@
virtual function void gen_load_store_instr();
bit enable_compressed_load_store;
riscv_instr instr;
- if(avail_regs.size() > 0) begin
- `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(avail_regs,
- unique{avail_regs};
- avail_regs[0] inside {[S0 : A5]};
- foreach(avail_regs[i]) {
- !(avail_regs[i] inside {cfg.reserved_regs, reserved_rd});
- },
- "Cannot randomize avail_regs")
- end
+ randomize_avail_regs();
if ((rs1_reg inside {[S0 : A5], SP}) && !cfg.disable_compressed_instr) begin
enable_compressed_load_store = 1;
end
- foreach(addr[i]) begin
+ foreach (addr[i]) begin
// Assign the allowed load/store instructions based on address alignment
// This is done separately rather than a constraint to improve the randomization performance
allowed_instr = {LB, LBU, SB};
@@ -450,6 +443,7 @@
}
`uvm_object_utils(riscv_load_store_rand_addr_instr_stream)
+ `uvm_object_new
virtual function void randomize_offset();
int offset_, addr_;
@@ -465,7 +459,7 @@
offset[i] = offset_;
addr[i] = addr_offset + offset_;
end
- endfunction `uvm_object_new
+ endfunction
virtual function void add_rs1_init_la_instr(riscv_reg_t gpr, int id, int base = 0);
riscv_instr instr[$];
@@ -524,3 +518,136 @@
endfunction
endclass
+
+class riscv_vector_unit_stride_load_store_instr_stream extends riscv_mem_access_stream;
+
+ typedef enum {B_ALIGNMENT, H_ALIGNMENT, W_ALIGNMENT, E_ALIGNMENT} alignment_e;
+
+ rand alignment_e alignment;
+ rand int unsigned data_page_id;
+ rand int unsigned num_mixed_instr;
+ rand riscv_reg_t rs1_reg;
+
+ constraint vec_mixed_instr_c {
+ num_mixed_instr inside {[0:10]};
+ }
+
+ constraint vec_rs1_c {
+ !(rs1_reg inside {cfg.reserved_regs, reserved_rd, ZERO});
+ }
+
+ constraint vec_data_page_id_c {
+ data_page_id < max_data_page_id;
+ }
+
+ constraint alignment_sew_c {
+ if (cfg.vector_cfg.vtype.vsew <= 16) {alignment != W_ALIGNMENT;}
+ if (cfg.vector_cfg.vtype.vsew <= 8) {alignment != H_ALIGNMENT;}
+ }
+
+ int base;
+ int max_load_store_addr;
+ riscv_instr load_store_instr;
+
+ `uvm_object_utils(riscv_vector_unit_stride_load_store_instr_stream)
+ `uvm_object_new
+
+ virtual function int get_addr_alignment_mask(int alignment_bytes);
+ return alignment_bytes - 1;
+ endfunction
+
+ function void post_randomize();
+ randomize_base();
+ // rs1 cannot be modified by other instructions
+ if(!(rs1_reg inside {reserved_rd})) reserved_rd = {reserved_rd, rs1_reg};
+ randomize_avail_regs();
+ gen_load_store_instr();
+ add_mixed_instr(num_mixed_instr);
+ add_rs1_init_la_instr(rs1_reg, data_page_id, base);
+ super.post_randomize();
+ endfunction
+
+ virtual function void randomize_base();
+ int ss = stride_span();
+ bit success;
+
+ repeat (10) begin
+ max_load_store_addr = data_page[data_page_id].size_in_bytes - ss;
+ if (max_load_store_addr >= 0) begin
+ success = 1'b1;
+ break;
+ end
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(data_page_id, data_page_id < max_data_page_id;)
+ end
+
+ assert (success) else begin
+ `uvm_fatal(`gfn, $sformatf({"Expected positive value for max_load_store_addr, got %0d.",
+ " Perhaps more memory needs to be allocated in the data pages for vector loads and stores.",
+ "\ndata_page_id:%0d\ndata_page[data_page_id].size_in_bytes:%0d\nstride_span:%0d",
+ "\nalignment:%s\nstride_bytes:%0d\nVLEN:%0d\nLMUL:%0d\ncfg.vector_cfg.vtype.vsew:%0d\n\n"},
+ max_load_store_addr, data_page_id, data_page[data_page_id].size_in_bytes, ss,
+ alignment.name(), stride_bytes(), VLEN,
+ cfg.vector_cfg.vtype.vlmul, cfg.vector_cfg.vtype.vsew))
+ end
+
+ `DV_CHECK_STD_RANDOMIZE_WITH_FATAL(base, base >= 0; base <= max_load_store_addr;)
+
+ if (!cfg.enable_unaligned_load_store) begin
+ base &= ~get_addr_alignment_mask(stride_bytes());
+ end
+ endfunction
+
+ virtual function int stride_span();
+ int num_elements = VLEN * cfg.vector_cfg.vtype.vlmul / cfg.vector_cfg.vtype.vsew;
+ stride_span = num_elements * stride_bytes();
+ endfunction
+
+ virtual function int stride_bytes();
+ stride_bytes = 0;
+ if (alignment == B_ALIGNMENT) stride_bytes = 1;
+ else if (alignment == H_ALIGNMENT) stride_bytes = 2;
+ else if (alignment == W_ALIGNMENT) stride_bytes = 4;
+ else if (alignment == E_ALIGNMENT) stride_bytes = cfg.vector_cfg.vtype.vsew;
+ endfunction
+
+ // Generate each load/store instruction
+ virtual function void gen_load_store_instr();
+ build_allowed_instr();
+ randomize_vec_load_store_instr();
+ instr_list.push_back(load_store_instr);
+ endfunction
+
+ virtual function void build_allowed_instr();
+ if (alignment == B_ALIGNMENT) add_byte_aligned_vec_load_stores();
+ else if (alignment == H_ALIGNMENT) add_h_aligned_vec_load_stores();
+ else if (alignment == W_ALIGNMENT) add_w_aligned_vec_load_stores();
+ else if (alignment == E_ALIGNMENT) add_element_vec_load_stores();
+ endfunction
+
+ virtual function void add_element_vec_load_stores();
+ allowed_instr = {VLE_V, VSE_V, allowed_instr};
+ endfunction
+
+ virtual function void add_byte_aligned_vec_load_stores();
+ allowed_instr = {VLB_V, VSB_V, VLBU_V, allowed_instr};
+ endfunction
+
+ virtual function void add_h_aligned_vec_load_stores();
+ allowed_instr = {VLH_V, VSH_V, VLHU_V, allowed_instr};
+ endfunction
+
+ virtual function void add_w_aligned_vec_load_stores();
+ allowed_instr = {VLW_V, VSW_V, VLWU_V, allowed_instr};
+ endfunction
+
+ virtual function void randomize_vec_load_store_instr();
+ load_store_instr = riscv_instr::get_load_store_instr(allowed_instr);
+ load_store_instr.m_cfg = cfg;
+ load_store_instr.has_rs1 = 0;
+ load_store_instr.has_imm = 0;
+ randomize_gpr(load_store_instr);
+ load_store_instr.rs1 = rs1_reg;
+ load_store_instr.process_load_store = 0;
+ endfunction
+
+endclass
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_page_table_list.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_page_table_list.sv
index d05bffd..5cc3772 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_page_table_list.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_page_table_list.sv
@@ -495,7 +495,7 @@
// Unset U bit
$sformatf("and x%0d, x%0d, x%0d", cfg.gpr[3], cfg.gpr[3], cfg.gpr[2]),
// Save PTE back to memory
- $sformatf("l%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
+ $sformatf("s%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
// Move to the next PTE
$sformatf("addi x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], XLEN/8),
// If not the end of the kernel space, process the next PTE
@@ -513,14 +513,14 @@
$sformatf("add x%0d, x%0d, x%0d", cfg.gpr[0], cfg.gpr[2], cfg.gpr[0]),
$sformatf("li x%0d, 0x%0x", cfg.gpr[2], ubit_mask),
// Assume 20 PTEs for kernel data pages
- $sformatf("addi x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], 20 * XLEN/8),
+ $sformatf("addi x%0d, x%0d, %0d", cfg.gpr[1], cfg.gpr[1], 20 * XLEN/8),
"2:",
// Load the PTE from the memory
$sformatf("l%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
// Unset U bit
$sformatf("and x%0d, x%0d, x%0d", cfg.gpr[3], cfg.gpr[3], cfg.gpr[2]),
// Save PTE back to memory
- $sformatf("l%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
+ $sformatf("s%0s x%0d, 0(x%0d)", load_store_unit, cfg.gpr[3], cfg.gpr[0]),
// Move to the next PTE
$sformatf("addi x%0d, x%0d, %0d", cfg.gpr[0], cfg.gpr[0], XLEN/8),
// If not the end of the kernel space, process the next PTE
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_vector_cfg.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_vector_cfg.sv
index dd58c91..90ce5c3 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_vector_cfg.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/src/riscv_vector_cfg.sv
@@ -1,5 +1,6 @@
/*
* Copyright 2020 Google LLC
+ * Copyright 2020 Andes Technology Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,21 +23,75 @@
rand vxrm_t vxrm;
rand bit vxsat;
+ // Allow only vector instructions from the random sequences
+ rand bit only_vec_instr;
+ constraint only_vec_instr_c {soft only_vec_instr == 0;}
+
+ // Allow vector floating-point instructions (Allows vtype.vsew to be set <16 or >32).
+ rand bit vec_fp;
+
+ // Allow vector narrowing or widening instructions.
+ rand bit vec_narrowing_widening;
+
+ // Allow vector quad-widening instructions.
+ rand bit vec_quad_widening;
+
+ constraint vec_quad_widening_c {
+ (!vec_narrowing_widening) -> (!vec_quad_widening);
+ // FP requires at least 16 bits and quad-widening requires no more than ELEN/4 bits.
+ (ELEN < 64) -> (!(vec_fp && vec_quad_widening));
+ }
+
+ rand bit allow_illegal_vec_instr;
+ constraint allow_illegal_vec_instr_c {soft allow_illegal_vec_instr == 0;}
+
+ // Cause frequent hazards for the Vector Registers:
+ // * Write-After-Read (WAR)
+ // * Read-After-Write (RAW)
+ // * Read-After-Read (RAR)
+ // * Write-After-Write (WAW)
+ // These hazard conditions are induced by keeping a small (~5) list of registers to select from.
+ rand bit vec_reg_hazards;
+
constraint legal_c {
solve vtype before vl;
solve vl before vstart;
- vstart <= vl;
- vtype.vsew <= $clog2(VLEN/8);
- vl <= (1 << ($clog2(VLEN/8) - vtype.vsew));
+ vstart inside {[0:vl]};
+ vl inside {[1:VLEN/vtype.vsew]};
}
// Basic constraint for initial bringup
constraint bringup_c {
vstart == 0;
- vl == (1 << ($clog2(VLEN/8) - vtype.vsew));
- vtype.vlmul == 0;
- vtype.vediv == 0;
- vtype.vsew == 2;
+ vl == VLEN/vtype.vsew;
+ vtype.vediv == 1;
+ }
+
+ // For all widening instructions, the destination element width must be a supported element
+ // width and the destination LMUL value must also be a supported LMUL value
+ constraint vlmul_c {
+ vtype.vlmul inside {1, 2, 4, 8};
+ vtype.vlmul <= MAX_LMUL;
+ if (vec_narrowing_widening) {
+ vtype.vlmul < 8;
+ }
+ if (vec_quad_widening) {
+ vtype.vlmul < 4;
+ }
+ }
+
+ constraint vsew_c {
+ vtype.vsew inside {8, 16, 32, 64, 128};
+ vtype.vsew <= ELEN;
+ // TODO: Determine the legal range of floating point format
+ if (vec_fp) {vtype.vsew inside {32};}
+ if (vec_narrowing_widening) {vtype.vsew < ELEN;}
+ if (vec_quad_widening) {vtype.vsew < (ELEN >> 1);}
+ }
+
+ constraint vdeiv_c {
+ vtype.vediv inside {1, 2, 4, 8};
+ vtype.vediv <= (vtype.vsew / SELEN);
}
`uvm_object_utils_begin(riscv_vector_cfg)
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv
index 46d466b..707e919 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/ml/riscv_core_setting.sv
@@ -54,14 +54,39 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// Maxium LMUL supported by the core
+parameter int MAX_LMUL = 8;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 1;
+
// ----------------------------------------------------------------------------
// Previleged CSR implementation
// ----------------------------------------------------------------------------
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/multi_harts/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/multi_harts/riscv_core_setting.sv
index 78d7724..04a2f55 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/multi_harts/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/multi_harts/riscv_core_setting.sv
@@ -54,11 +54,35 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// Maxium LMUL supported by the core
+parameter int MAX_LMUL = 8;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 2;
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv
index c93e3f3..49c97c8 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32i/riscv_core_setting.sv
@@ -54,14 +54,36 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 1;
+
// ----------------------------------------------------------------------------
// Previleged CSR implementation
// ----------------------------------------------------------------------------
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv
index 1fc0348..1aaf1a1 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32imc/riscv_core_setting.sv
@@ -54,11 +54,35 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// Maxium LMUL supported by the core
+parameter int MAX_LMUL = 8;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 1;
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv
index dfc99c8..df33010 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv32imcb/riscv_core_setting.sv
@@ -54,11 +54,35 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// Maxium LMUL supported by the core
+parameter int MAX_LMUL = 8;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 1;
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv
index 386c675..4ca59cd 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gc/riscv_core_setting.sv
@@ -54,11 +54,35 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// Maxium LMUL supported by the core
+parameter int MAX_LMUL = 8;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 1;
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gcv/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gcv/riscv_core_setting.sv
index f9033d1..d418120 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gcv/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gcv/riscv_core_setting.sv
@@ -21,17 +21,17 @@
parameter int XLEN = 64;
// Parameter for SATP mode, set to BARE if address translation is not supported
-parameter satp_mode_t SATP_MODE = SV39;
+parameter satp_mode_t SATP_MODE = BARE;
// Supported Privileged mode
-privileged_mode_t supported_privileged_mode[] = {USER_MODE, SUPERVISOR_MODE, MACHINE_MODE};
+privileged_mode_t supported_privileged_mode[] = {MACHINE_MODE};
// Unsupported instructions
-riscv_instr_name_t unsupported_instr[] = {VWMACCSU};
+riscv_instr_name_t unsupported_instr[] = {};
// ISA supported by the processor
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV64I, RV64M, RV32C, RV64C, RV32A, RV64A,
- RV32F, RV64F, RV32D, RV64D, RV32V, RV64V};
+ RV32F, RV64F, RV32D, RV64D, RVV};
// Interrupt mode support
mtvec_mode_t supported_interrupt_mode[$] = {DIRECT, VECTORED};
@@ -54,14 +54,38 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 1;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// Maxium LMUL supported by the core
+parameter int MAX_LMUL = 8;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 1;
+
// ----------------------------------------------------------------------------
// Previleged CSR implementation
// ----------------------------------------------------------------------------
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gcv/testlist.yaml b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gcv/testlist.yaml
index 350e43b..50698ab 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gcv/testlist.yaml
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64gcv/testlist.yaml
@@ -47,3 +47,19 @@
iterations: 2
gen_test: riscv_instr_base_test
rtl_test: core_base_test
+
+- test: riscv_vector_load_store_test
+ description: >
+ Vector load/store random test
+ gen_opts: >
+ +instr_cnt=10000
+ +num_of_sub_program=0
+ +enable_floating_point=1
+ +enable_vector_extension=1
+ +directed_instr_0=riscv_vector_unit_stride_load_store_instr_stream,4
+ +no_branch_jump=1
+ +boot_mode=m
+ +no_csr_instr=1
+ iterations: 2
+ gen_test: riscv_instr_base_test
+ rtl_test: core_base_test
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv
index 8511dc4..0071ffa 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64imc/riscv_core_setting.sv
@@ -54,11 +54,34 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// Maxium LMUL supported by the core
+parameter int MAX_LMUL = 8;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 1;
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64imcb/riscv_core_setting.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64imcb/riscv_core_setting.sv
index 2f67acf..3bf90a5 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64imcb/riscv_core_setting.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/target/rv64imcb/riscv_core_setting.sv
@@ -54,11 +54,35 @@
// Support unaligned load/store
bit support_unaligned_load_store = 1'b1;
+// GPR setting
+parameter int NUM_FLOAT_GPR = 32;
+parameter int NUM_GPR = 32;
+parameter int NUM_VEC_GPR = 32;
+
+// ----------------------------------------------------------------------------
+// Vector extension configuration
+// ----------------------------------------------------------------------------
+
// Parameter for vector extension
parameter int VECTOR_EXTENSION_ENABLE = 0;
+
parameter int VLEN = 512;
-parameter int ELEN = 64;
-parameter int SLEN = 64;
+
+// Maximum size of a single vector element
+parameter int ELEN = 32;
+
+// Minimum size of a sub-element, which must be at most 8-bits.
+parameter int SELEN = 8;
+
+// Maximum size of a single vector element (encoded in vsew format)
+parameter int VELEN = int'($ln(ELEN)/$ln(2)) - 3;
+
+// Maxium LMUL supported by the core
+parameter int MAX_LMUL = 8;
+
+// ----------------------------------------------------------------------------
+// Multi-harts configuration
+// ----------------------------------------------------------------------------
// Number of harts
parameter int NUM_HARTS = 1;
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv
index fb0fa20..8bfc625 100644
--- a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/test/riscv_instr_cov_test.sv
@@ -132,11 +132,12 @@
riscv_instr instr;
instr = riscv_instr::get_instr(instr_name);
if (instr.group inside {RV32I, RV32M, RV32C, RV64I, RV64M, RV64C,
- RV32F, RV32B, RV64B}) begin
+ RV32F, RV64F, RV32D, RV64D,
+ RV32B, RV64B}) begin
assign_trace_info_to_instr(instr);
+ instr.pre_sample();
+ instr_cg.sample(instr);
end
- instr.pre_sample();
- instr_cg.sample(instr);
return 1'b1;
end
end
@@ -177,6 +178,27 @@
instr_name[i] = "_";
end
end
+
+ case (instr_name)
+ // rename to new name as ovpsim still uses old name
+ "FMV_S_X": instr_name = "FMV_W_X";
+ "FMV_X_S": instr_name = "FMV_X_W";
+ // convert Pseudoinstructions
+ // fmv.s rd, rs fsgnj.s rd, rs, rs Copy single-precision register
+ // fabs.s rd, rs fsgnjx.s rd, rs, rs Single-precision absolute value
+ // fneg.s rd, rs fsgnjn.s rd, rs, rs Single-precision negate
+ // fmv.d rd, rs fsgnj.d rd, rs, rs Copy double-precision register
+ // fabs.d rd, rs fsgnjx.d rd, rs, rs Double-precision absolute value
+ // fneg.d rd, rs fsgnjn.d rd, rs, rs Double-precision negate
+ "FMV_S": instr_name = "FSGNJ_S";
+ "FABS_S": instr_name = "FSGNJX_S";
+ "FNEG_S": instr_name = "FSGNJN_S";
+ "FMV_D": instr_name = "FSGNJ_D";
+ "FABS_D": instr_name = "FSGNJX_D";
+ "FNEG_D": instr_name = "FSGNJN_D";
+ default: ;
+ endcase
+
return instr_name;
endfunction : process_instr_name
diff --git a/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/user_extension/user_init.s b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/user_extension/user_init.s
new file mode 100644
index 0000000..2f8b49f
--- /dev/null
+++ b/hw/vendor/lowrisc_ibex/vendor/google_riscv-dv/user_extension/user_init.s
@@ -0,0 +1,2 @@
+# Add custom initialization assembly code here
+# This file will be included at the very beginning of the program