mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-20 12:08:05 -04:00
[rtl] Add bus integrity checking
Extra bits are added alongside read/write data for the instruction and data buses to facilitate data integrity checking. Ibex testbench extended to generate the expected bits. All other top-levels modified to add the new signals (which are mostly ignored). Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
This commit is contained in:
parent
14115ea3a8
commit
48f11c6733
20 changed files with 341 additions and 206 deletions
|
@ -35,51 +35,54 @@ Instantiation Template
|
|||
.DmExceptionAddr ( 32'h1A110808 )
|
||||
) u_top (
|
||||
// Clock and reset
|
||||
.clk_i (),
|
||||
.rst_ni (),
|
||||
.test_en_i (),
|
||||
.scan_rst_ni (),
|
||||
.ram_cfg_i (),
|
||||
.clk_i (),
|
||||
.rst_ni (),
|
||||
.test_en_i (),
|
||||
.scan_rst_ni (),
|
||||
.ram_cfg_i (),
|
||||
|
||||
// Configuration
|
||||
.hart_id_i (),
|
||||
.boot_addr_i (),
|
||||
.hart_id_i (),
|
||||
.boot_addr_i (),
|
||||
|
||||
// Instruction memory interface
|
||||
.instr_req_o (),
|
||||
.instr_gnt_i (),
|
||||
.instr_rvalid_i (),
|
||||
.instr_addr_o (),
|
||||
.instr_rdata_i (),
|
||||
.instr_err_i (),
|
||||
.instr_req_o (),
|
||||
.instr_gnt_i (),
|
||||
.instr_rvalid_i (),
|
||||
.instr_addr_o (),
|
||||
.instr_rdata_i (),
|
||||
.instr_rdata_intg_i (),
|
||||
.instr_err_i (),
|
||||
|
||||
// Data memory interface
|
||||
.data_req_o (),
|
||||
.data_gnt_i (),
|
||||
.data_rvalid_i (),
|
||||
.data_we_o (),
|
||||
.data_be_o (),
|
||||
.data_addr_o (),
|
||||
.data_wdata_o (),
|
||||
.data_rdata_i (),
|
||||
.data_err_i (),
|
||||
.data_req_o (),
|
||||
.data_gnt_i (),
|
||||
.data_rvalid_i (),
|
||||
.data_we_o (),
|
||||
.data_be_o (),
|
||||
.data_addr_o (),
|
||||
.data_wdata_o (),
|
||||
.data_wdata_intg_o (),
|
||||
.data_rdata_i (),
|
||||
.data_rdata_intg_i (),
|
||||
.data_err_i (),
|
||||
|
||||
// Interrupt inputs
|
||||
.irq_software_i (),
|
||||
.irq_timer_i (),
|
||||
.irq_external_i (),
|
||||
.irq_fast_i (),
|
||||
.irq_nm_i (),
|
||||
.irq_software_i (),
|
||||
.irq_timer_i (),
|
||||
.irq_external_i (),
|
||||
.irq_fast_i (),
|
||||
.irq_nm_i (),
|
||||
|
||||
// Debug interface
|
||||
.debug_req_i (),
|
||||
.crash_dump_o (),
|
||||
.debug_req_i (),
|
||||
.crash_dump_o (),
|
||||
|
||||
// Special control signals
|
||||
.fetch_enable_i (),
|
||||
.alert_minor_o (),
|
||||
.alert_major_o (),
|
||||
.core_sleep_o ()
|
||||
.fetch_enable_i (),
|
||||
.alert_minor_o (),
|
||||
.alert_major_o (),
|
||||
.core_sleep_o ()
|
||||
);
|
||||
|
||||
Parameters
|
||||
|
|
|
@ -45,26 +45,28 @@ The main difference is that the instruction interface does not allow for write t
|
|||
|
||||
.. tabularcolumns:: |p{4cm}|l|p{9cm}|
|
||||
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| Signal | Direction | Description |
|
||||
+=========================+===========+===============================================+
|
||||
| ``instr_req_o`` | output | Request valid, must stay high until |
|
||||
| | | ``instr_gnt_i`` is high for one cycle |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_addr_o[31:0]`` | output | Address, word aligned |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_gnt_i`` | input | The other side accepted the request. |
|
||||
| | | ``instr_req_o`` may be deasserted in the next |
|
||||
| | | cycle. |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_rvalid_i`` | input | ``instr_rdata_i`` holds valid data when |
|
||||
| | | ``instr_rvalid_i`` is high. This signal will |
|
||||
| | | be high for exactly one cycle per request. |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_rdata_i[31:0]`` | input | Data read from memory |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_err_i`` | input | Memory access error |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
+-----------------------------+-----------+-----------------------------------------------+
|
||||
| Signal | Direction | Description |
|
||||
+=============================+===========+===============================================+
|
||||
| ``instr_req_o`` | output | Request valid, must stay high until |
|
||||
| | | ``instr_gnt_i`` is high for one cycle |
|
||||
+-----------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_addr_o[31:0]`` | output | Address, word aligned |
|
||||
+-----------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_gnt_i`` | input | The other side accepted the request. |
|
||||
| | | ``instr_req_o`` may be deasserted in the next |
|
||||
| | | cycle. |
|
||||
+-----------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_rvalid_i`` | input | ``instr_rdata_i`` holds valid data when |
|
||||
| | | ``instr_rvalid_i`` is high. This signal will |
|
||||
| | | be high for exactly one cycle per request. |
|
||||
+-----------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_rdata_i[31:0]`` | input | Data read from memory |
|
||||
+-----------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_rdata_intg_i[6:0]`` | input | Data integrity bits from memory |
|
||||
+-----------------------------+-----------+-----------------------------------------------+
|
||||
| ``instr_err_i`` | input | Memory access error |
|
||||
+-----------------------------+-----------+-----------------------------------------------+
|
||||
|
||||
|
||||
Misaligned Accesses
|
||||
|
|
|
@ -14,39 +14,56 @@ Data-Side Memory Interface
|
|||
|
||||
Signals that are used by the LSU:
|
||||
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| Signal | Direction | Description |
|
||||
+=========================+===========+===============================================+
|
||||
| ``data_req_o`` | output | Request valid, must stay high until |
|
||||
| | | ``data_gnt_i`` is high for one cycle |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_addr_o[31:0]`` | output | Address, word aligned |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_we_o`` | output | Write Enable, high for writes, low for |
|
||||
| | | reads. Sent together with ``data_req_o`` |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_be_o[3:0]`` | output | Byte Enable. Is set for the bytes to |
|
||||
| | | write/read, sent together with ``data_req_o`` |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_wdata_o[31:0]`` | output | Data to be written to memory, sent together |
|
||||
| | | with ``data_req_o`` |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_gnt_i`` | input | The other side accepted the request. |
|
||||
| | | Outputs may change in the next cycle. |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_rvalid_i`` | input | ``data_err_i`` and ``data_rdata_i`` hold |
|
||||
| | | valid data when ``data_rvalid_i`` is high. |
|
||||
| | | This signal will be high for exactly one |
|
||||
| | | cycle per request. |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_err_i`` | input | Error response from the bus or the memory: |
|
||||
| | | request cannot be handled. High in case of an |
|
||||
| | | error. |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_rdata_i[31:0]`` | input | Data read from memory |
|
||||
+-------------------------+-----------+-----------------------------------------------+
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| Signal | Direction | Description |
|
||||
+============================+===========+===============================================+
|
||||
| ``data_req_o`` | output | Request valid, must stay high until |
|
||||
| | | ``data_gnt_i`` is high for one cycle |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_addr_o[31:0]`` | output | Address, word aligned |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_we_o`` | output | Write Enable, high for writes, low for |
|
||||
| | | reads. Sent together with ``data_req_o`` |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_be_o[3:0]`` | output | Byte Enable. Is set for the bytes to |
|
||||
| | | write/read, sent together with ``data_req_o`` |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_wdata_o[31:0]`` | output | Data to be written to memory, sent together |
|
||||
| | | with ``data_req_o`` |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_wdata_intg_o[6:0]`` | output | Integrity bits to be written to memory, sent |
|
||||
| | | together with ``data_req_o`` (not used unless |
|
||||
| | | the SecureIbex parameter is set) |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_gnt_i`` | input | The other side accepted the request. |
|
||||
| | | Outputs may change in the next cycle. |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_rvalid_i`` | input | ``data_err_i`` and ``data_rdata_i`` hold |
|
||||
| | | valid data when ``data_rvalid_i`` is high. |
|
||||
| | | This signal will be high for exactly one |
|
||||
| | | cycle per request. |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_err_i`` | input | Error response from the bus or the memory: |
|
||||
| | | request cannot be handled. High in case of an |
|
||||
| | | error. |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_rdata_i[31:0]`` | input | Data read from memory |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
| ``data_rdata_intg_i[6:0]`` | input | Integrity bits read from memory (ignored |
|
||||
| | | unless the SecureIbex parameter is set) |
|
||||
+----------------------------+-----------+-----------------------------------------------+
|
||||
|
||||
|
||||
Bus Integrity Checking
|
||||
----------------------
|
||||
|
||||
The core can optionally generate and verify check bits sent alongside the data for memory accesses.
|
||||
Checkbits are generated and checked using a 39/32 Hsaio code (see :file:`vendor/lowrisc_ip/ip/prim/rtl/prim_secded_39_32_enc.sv`).
|
||||
When this feature is used, any mismatch in checkbits will generate a major alert.
|
||||
|
||||
This feature is only used if the core is configured with the SecureIbex parameter set.
|
||||
For all other configurations, the integrity signals can be ignored.
|
||||
|
||||
Misaligned Accesses
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -57,6 +57,13 @@ This will make the insertion interval of dummy instructions much harder for an a
|
|||
Note that the dummy instruction feature inserts multiply and divide instructions.
|
||||
The core must be configured with a multiplier (`RV32M != ibex_pkg::RV32MNone`) or errors will occur using this feature.
|
||||
|
||||
Bus integrity checking
|
||||
----------------------
|
||||
|
||||
Extra signals are available alongside the instruction and data side memory channels to support bus integrity checking.
|
||||
When the SecureIbex parameter is set, incoming data will be checked against the supplied checkbits, and a major alert signalled if there is a mismatch.
|
||||
Write data can be checked against the supplied checkbits at its destination to confirm integrity.
|
||||
|
||||
Register file ECC
|
||||
-----------------
|
||||
|
||||
|
@ -78,6 +85,7 @@ Shadow CSRs
|
|||
Certain critical CSRs (`mstatus`, `mtvec`, `cpuctrl`, `pmpcfg` and `pmpaddr`) have extra glitch detection enabled.
|
||||
This creates a second copy of the register which stores a complemented version of the main CSR data.
|
||||
A constant check is made that the two copies are consistent, and a major alert is signalled if not.
|
||||
Note that this feature is not currently used when the SecureIbex parameter is set due to overlap with dual core lockstep.
|
||||
|
||||
Dual core lockstep
|
||||
------------------
|
||||
|
|
|
@ -130,47 +130,50 @@ module ibex_riscv_compliance (
|
|||
.DmHaltAddr (32'h00000000 ),
|
||||
.DmExceptionAddr (32'h00000000 )
|
||||
) u_top (
|
||||
.clk_i (clk_sys ),
|
||||
.rst_ni (rst_sys_n ),
|
||||
.clk_i (clk_sys ),
|
||||
.rst_ni (rst_sys_n ),
|
||||
|
||||
.test_en_i ('b0 ),
|
||||
.scan_rst_ni (1'b1 ),
|
||||
.ram_cfg_i ('b0 ),
|
||||
.test_en_i ('b0 ),
|
||||
.scan_rst_ni (1'b1 ),
|
||||
.ram_cfg_i ('b0 ),
|
||||
|
||||
.hart_id_i (32'b0 ),
|
||||
.hart_id_i (32'b0 ),
|
||||
// First instruction executed is at 0x0 + 0x80
|
||||
.boot_addr_i (32'h00000000 ),
|
||||
.boot_addr_i (32'h00000000 ),
|
||||
|
||||
.instr_req_o (host_req[CoreI] ),
|
||||
.instr_gnt_i (host_gnt[CoreI] ),
|
||||
.instr_rvalid_i (host_rvalid[CoreI]),
|
||||
.instr_addr_o (host_addr[CoreI] ),
|
||||
.instr_rdata_i (host_rdata[CoreI] ),
|
||||
.instr_err_i (host_err[CoreI] ),
|
||||
.instr_req_o (host_req[CoreI] ),
|
||||
.instr_gnt_i (host_gnt[CoreI] ),
|
||||
.instr_rvalid_i (host_rvalid[CoreI]),
|
||||
.instr_addr_o (host_addr[CoreI] ),
|
||||
.instr_rdata_i (host_rdata[CoreI] ),
|
||||
.instr_rdata_intg_i ('0 ),
|
||||
.instr_err_i (host_err[CoreI] ),
|
||||
|
||||
.data_req_o (host_req[CoreD] ),
|
||||
.data_gnt_i (host_gnt[CoreD] ),
|
||||
.data_rvalid_i (host_rvalid[CoreD]),
|
||||
.data_we_o (host_we[CoreD] ),
|
||||
.data_be_o (host_be[CoreD] ),
|
||||
.data_addr_o (host_addr[CoreD] ),
|
||||
.data_wdata_o (host_wdata[CoreD] ),
|
||||
.data_rdata_i (host_rdata[CoreD] ),
|
||||
.data_err_i (host_err[CoreD] ),
|
||||
.data_req_o (host_req[CoreD] ),
|
||||
.data_gnt_i (host_gnt[CoreD] ),
|
||||
.data_rvalid_i (host_rvalid[CoreD]),
|
||||
.data_we_o (host_we[CoreD] ),
|
||||
.data_be_o (host_be[CoreD] ),
|
||||
.data_addr_o (host_addr[CoreD] ),
|
||||
.data_wdata_o (host_wdata[CoreD] ),
|
||||
.data_wdata_intg_o ( ),
|
||||
.data_rdata_i (host_rdata[CoreD] ),
|
||||
.data_rdata_intg_i ('0 ),
|
||||
.data_err_i (host_err[CoreD] ),
|
||||
|
||||
.irq_software_i (1'b0 ),
|
||||
.irq_timer_i (1'b0 ),
|
||||
.irq_external_i (1'b0 ),
|
||||
.irq_fast_i (15'b0 ),
|
||||
.irq_nm_i (1'b0 ),
|
||||
.irq_software_i (1'b0 ),
|
||||
.irq_timer_i (1'b0 ),
|
||||
.irq_external_i (1'b0 ),
|
||||
.irq_fast_i (15'b0 ),
|
||||
.irq_nm_i (1'b0 ),
|
||||
|
||||
.debug_req_i ('b0 ),
|
||||
.crash_dump_o ( ),
|
||||
.debug_req_i ('b0 ),
|
||||
.crash_dump_o ( ),
|
||||
|
||||
.fetch_enable_i ('b1 ),
|
||||
.alert_minor_o ( ),
|
||||
.alert_major_o ( ),
|
||||
.core_sleep_o ( )
|
||||
.fetch_enable_i ('b1 ),
|
||||
.alert_minor_o ( ),
|
||||
.alert_major_o ( ),
|
||||
.core_sleep_o ( )
|
||||
);
|
||||
|
||||
// SRAM block for instruction and data storage
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
|
||||
interface ibex_mem_intf#(
|
||||
parameter int ADDR_WIDTH = 32,
|
||||
parameter int DATA_WIDTH = 32
|
||||
parameter int DATA_WIDTH = 32,
|
||||
parameter int INTG_WIDTH = 7
|
||||
) (
|
||||
input clk
|
||||
);
|
||||
|
@ -17,7 +18,9 @@ interface ibex_mem_intf#(
|
|||
wire [DATA_WIDTH/8-1:0] be;
|
||||
wire rvalid;
|
||||
wire [DATA_WIDTH-1:0] wdata;
|
||||
wire [INTG_WIDTH-1:0] wintg;
|
||||
wire [DATA_WIDTH-1:0] rdata;
|
||||
wire [INTG_WIDTH-1:0] rintg;
|
||||
wire error;
|
||||
|
||||
clocking request_driver_cb @(posedge clk);
|
||||
|
@ -29,7 +32,9 @@ interface ibex_mem_intf#(
|
|||
output be;
|
||||
input rvalid;
|
||||
output wdata;
|
||||
output wintg;
|
||||
input rdata;
|
||||
input rintg;
|
||||
input error;
|
||||
endclocking
|
||||
|
||||
|
@ -42,7 +47,9 @@ interface ibex_mem_intf#(
|
|||
input be;
|
||||
output rvalid;
|
||||
input wdata;
|
||||
input wintg;
|
||||
output rdata;
|
||||
output rintg;
|
||||
output error;
|
||||
endclocking
|
||||
|
||||
|
@ -55,7 +62,9 @@ interface ibex_mem_intf#(
|
|||
input be;
|
||||
input rvalid;
|
||||
input wdata;
|
||||
input wintg;
|
||||
input rdata;
|
||||
input rintg;
|
||||
input error;
|
||||
endclocking
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ package ibex_mem_intf_agent_pkg;
|
|||
|
||||
parameter int DATA_WIDTH = 32;
|
||||
parameter int ADDR_WIDTH = 32;
|
||||
parameter int INTG_WIDTH = 7;
|
||||
|
||||
typedef enum { READ, WRITE } rw_e;
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ class ibex_mem_intf_monitor extends uvm_monitor;
|
|||
if(vif.monitor_cb.we) begin
|
||||
trans_collected.read_write = WRITE;
|
||||
trans_collected.data = vif.monitor_cb.wdata;
|
||||
trans_collected.intg = vif.monitor_cb.wintg;
|
||||
end else begin
|
||||
trans_collected.read_write = READ;
|
||||
end
|
||||
|
@ -81,6 +82,7 @@ class ibex_mem_intf_monitor extends uvm_monitor;
|
|||
vif.wait_clks(1);
|
||||
while(vif.monitor_cb.rvalid === 0);
|
||||
trans_collected.data = vif.monitor_cb.rdata;
|
||||
trans_collected.intg = vif.monitor_cb.rintg;
|
||||
item_collected_port.write(trans_collected);
|
||||
end
|
||||
endtask : collect_data_phase
|
||||
|
|
|
@ -49,6 +49,7 @@ class ibex_mem_intf_request_driver extends uvm_driver #(ibex_mem_intf_seq_item);
|
|||
vif.request_driver_cb.request <= 'h0;
|
||||
vif.request_driver_cb.addr <= 'hz;
|
||||
vif.request_driver_cb.wdata <= 'hz;
|
||||
vif.request_driver_cb.wintg <= 'hz;
|
||||
vif.request_driver_cb.be <= 'bz;
|
||||
vif.request_driver_cb.we <= 'bz;
|
||||
end
|
||||
|
@ -63,11 +64,13 @@ class ibex_mem_intf_request_driver extends uvm_driver #(ibex_mem_intf_seq_item);
|
|||
vif.request_driver_cb.be <= trans.be;
|
||||
vif.request_driver_cb.we <= trans.read_write;
|
||||
vif.request_driver_cb.wdata <= trans.data;
|
||||
vif.request_driver_cb.wintg <= trans.intg;
|
||||
wait (vif.request_driver_cb.grant === 1'b1);
|
||||
vif.wait_clks(1);
|
||||
vif.request_driver_cb.request <= 'h0;
|
||||
vif.request_driver_cb.addr <= 'hz;
|
||||
vif.request_driver_cb.wdata <= 'hz;
|
||||
vif.request_driver_cb.wintg <= 'hz;
|
||||
vif.request_driver_cb.be <= 'bz;
|
||||
vif.request_driver_cb.we <= 'bz;
|
||||
rdata_queue.put(trans);
|
||||
|
@ -81,6 +84,7 @@ class ibex_mem_intf_request_driver extends uvm_driver #(ibex_mem_intf_seq_item);
|
|||
while(vif.rvalid !== 1'b1) vif.wait_clks(1);
|
||||
if(tr.read_write == READ)
|
||||
tr.data = vif.request_driver_cb.rdata;
|
||||
tr.intg = vif.request_driver_cb.rintg;
|
||||
seq_item_port.put_response(tr);
|
||||
end
|
||||
endtask : collect_response
|
||||
|
|
|
@ -59,6 +59,7 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
|
|||
vif.response_driver_cb.rvalid <= 1'b0;
|
||||
vif.response_driver_cb.grant <= 1'b0;
|
||||
vif.response_driver_cb.rdata <= 'b0;
|
||||
vif.response_driver_cb.rintg <= 'b0;
|
||||
vif.response_driver_cb.error <= 1'b0;
|
||||
endtask : reset_signals
|
||||
|
||||
|
@ -113,7 +114,8 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
|
|||
vif.wait_clks(1);
|
||||
vif.response_driver_cb.rvalid <= 1'b0;
|
||||
vif.response_driver_cb.rdata <= 'x;
|
||||
vif.response_driver_cb.error <= 1'b0;
|
||||
vif.response_driver_cb.rintg <= 'x;
|
||||
vif.response_driver_cb.error <= 'x;
|
||||
rdata_queue.get(tr);
|
||||
if(vif.response_driver_cb.reset) continue;
|
||||
vif.wait_clks(tr.rvalid_delay);
|
||||
|
@ -121,6 +123,7 @@ class ibex_mem_intf_response_driver extends uvm_driver #(ibex_mem_intf_seq_item)
|
|||
vif.response_driver_cb.rvalid <= 1'b1;
|
||||
vif.response_driver_cb.error <= tr.error;
|
||||
vif.response_driver_cb.rdata <= tr.data;
|
||||
vif.response_driver_cb.rintg <= tr.intg;
|
||||
end
|
||||
end
|
||||
endtask : send_read_data
|
||||
|
|
|
@ -31,6 +31,7 @@ class ibex_mem_intf_response_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
|
|||
bit [ADDR_WIDTH-1:0] aligned_addr;
|
||||
bit [DATA_WIDTH-1:0] rand_data;
|
||||
bit [DATA_WIDTH-1:0] read_data;
|
||||
bit [INTG_WIDTH-1:0] read_intg;
|
||||
p_sequencer.addr_ph_port.get(item);
|
||||
req = ibex_mem_intf_seq_item::type_id::create("req");
|
||||
error_synch = 1'b0;
|
||||
|
@ -38,6 +39,7 @@ class ibex_mem_intf_response_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
|
|||
addr == item.addr;
|
||||
read_write == item.read_write;
|
||||
data == item.data;
|
||||
intg == item.intg;
|
||||
be == item.be;
|
||||
rvalid_delay dist {
|
||||
min_rvalid_delay :/ 5,
|
||||
|
@ -69,6 +71,8 @@ class ibex_mem_intf_response_seq extends uvm_sequence #(ibex_mem_intf_seq_item);
|
|||
end
|
||||
end
|
||||
end
|
||||
// Add correct integrity bits
|
||||
{req.intg, req.data} = prim_secded_pkg::prim_secded_39_32_enc(req.data);
|
||||
`uvm_info(get_full_name(), $sformatf("Response transfer:\n%0s", req.sprint()), UVM_HIGH)
|
||||
start_item(req);
|
||||
finish_item(req);
|
||||
|
|
|
@ -11,6 +11,7 @@ class ibex_mem_intf_seq_item extends uvm_sequence_item;
|
|||
rand bit [ADDR_WIDTH-1:0] addr;
|
||||
rand rw_e read_write;
|
||||
rand bit [DATA_WIDTH-1:0] data;
|
||||
rand bit [INTG_WIDTH-1:0] intg;
|
||||
rand bit [DATA_WIDTH/8-1:0] be;
|
||||
rand bit [3:0] gnt_delay;
|
||||
rand bit [3:0] req_delay;
|
||||
|
@ -22,6 +23,7 @@ class ibex_mem_intf_seq_item extends uvm_sequence_item;
|
|||
`uvm_field_enum (rw_e, read_write, UVM_DEFAULT)
|
||||
`uvm_field_int (be, UVM_DEFAULT)
|
||||
`uvm_field_int (data, UVM_DEFAULT)
|
||||
`uvm_field_int (intg, UVM_DEFAULT)
|
||||
`uvm_field_int (gnt_delay, UVM_DEFAULT)
|
||||
`uvm_field_int (rvalid_delay, UVM_DEFAULT)
|
||||
`uvm_field_int (error, UVM_DEFAULT)
|
||||
|
|
|
@ -28,6 +28,7 @@ ${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_72_64_dec.sv
|
|||
// wrappers around the prim_* modules to instantiate the prim_generic_* ones,
|
||||
// see https://github.com/lowRISC/ibex/issues/893.
|
||||
${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_pkg.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_secded_pkg.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_ram_1p_pkg.sv
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim_generic/rtl/prim_generic_ram_1p.sv
|
||||
${PRJ_DIR}/dv/uvm/core_ibex/common/prim/prim_ram_1p.sv
|
||||
|
|
|
@ -77,46 +77,49 @@ module core_ibex_tb_top;
|
|||
.SecureIbex (SecureIbex ),
|
||||
.BranchPredictor (BranchPredictor )
|
||||
) dut (
|
||||
.clk_i (clk ),
|
||||
.rst_ni (rst_n ),
|
||||
.clk_i (clk ),
|
||||
.rst_ni (rst_n ),
|
||||
|
||||
.test_en_i (1'b0 ),
|
||||
.scan_rst_ni (1'b1 ),
|
||||
.ram_cfg_i ('b0 ),
|
||||
.test_en_i (1'b0 ),
|
||||
.scan_rst_ni (1'b1 ),
|
||||
.ram_cfg_i ('b0 ),
|
||||
|
||||
.hart_id_i (32'b0 ),
|
||||
.boot_addr_i (32'h`BOOT_ADDR ), // align with spike boot address
|
||||
.hart_id_i (32'b0 ),
|
||||
.boot_addr_i (32'h`BOOT_ADDR ), // align with spike boot address
|
||||
|
||||
.instr_req_o (instr_mem_vif.request),
|
||||
.instr_gnt_i (instr_mem_vif.grant ),
|
||||
.instr_rvalid_i (instr_mem_vif.rvalid ),
|
||||
.instr_addr_o (instr_mem_vif.addr ),
|
||||
.instr_rdata_i (instr_mem_vif.rdata ),
|
||||
.instr_err_i (instr_mem_vif.error ),
|
||||
.instr_req_o (instr_mem_vif.request),
|
||||
.instr_gnt_i (instr_mem_vif.grant ),
|
||||
.instr_rvalid_i (instr_mem_vif.rvalid ),
|
||||
.instr_addr_o (instr_mem_vif.addr ),
|
||||
.instr_rdata_i (instr_mem_vif.rdata ),
|
||||
.instr_rdata_intg_i (instr_mem_vif.rintg ),
|
||||
.instr_err_i (instr_mem_vif.error ),
|
||||
|
||||
.data_req_o (data_mem_vif.request ),
|
||||
.data_gnt_i (data_mem_vif.grant ),
|
||||
.data_rvalid_i (data_mem_vif.rvalid ),
|
||||
.data_addr_o (data_mem_vif.addr ),
|
||||
.data_we_o (data_mem_vif.we ),
|
||||
.data_be_o (data_mem_vif.be ),
|
||||
.data_rdata_i (data_mem_vif.rdata ),
|
||||
.data_wdata_o (data_mem_vif.wdata ),
|
||||
.data_err_i (data_mem_vif.error ),
|
||||
.data_req_o (data_mem_vif.request ),
|
||||
.data_gnt_i (data_mem_vif.grant ),
|
||||
.data_rvalid_i (data_mem_vif.rvalid ),
|
||||
.data_addr_o (data_mem_vif.addr ),
|
||||
.data_we_o (data_mem_vif.we ),
|
||||
.data_be_o (data_mem_vif.be ),
|
||||
.data_rdata_i (data_mem_vif.rdata ),
|
||||
.data_rdata_intg_i (data_mem_vif.rintg ),
|
||||
.data_wdata_o (data_mem_vif.wdata ),
|
||||
.data_wdata_intg_o (data_mem_vif.wintg ),
|
||||
.data_err_i (data_mem_vif.error ),
|
||||
|
||||
.irq_software_i (irq_vif.irq_software ),
|
||||
.irq_timer_i (irq_vif.irq_timer ),
|
||||
.irq_external_i (irq_vif.irq_external ),
|
||||
.irq_fast_i (irq_vif.irq_fast ),
|
||||
.irq_nm_i (irq_vif.irq_nm ),
|
||||
.irq_software_i (irq_vif.irq_software ),
|
||||
.irq_timer_i (irq_vif.irq_timer ),
|
||||
.irq_external_i (irq_vif.irq_external ),
|
||||
.irq_fast_i (irq_vif.irq_fast ),
|
||||
.irq_nm_i (irq_vif.irq_nm ),
|
||||
|
||||
.debug_req_i (dut_if.debug_req ),
|
||||
.crash_dump_o ( ),
|
||||
.debug_req_i (dut_if.debug_req ),
|
||||
.crash_dump_o ( ),
|
||||
|
||||
.fetch_enable_i (dut_if.fetch_enable ),
|
||||
.alert_minor_o (dut_if.alert_minor ),
|
||||
.alert_major_o (dut_if.alert_major ),
|
||||
.core_sleep_o (dut_if.core_sleep )
|
||||
.fetch_enable_i (dut_if.fetch_enable ),
|
||||
.alert_minor_o (dut_if.alert_minor ),
|
||||
.alert_major_o (dut_if.alert_major ),
|
||||
.core_sleep_o (dut_if.core_sleep )
|
||||
);
|
||||
|
||||
// We should never see any alerts triggered in normal testing
|
||||
|
|
|
@ -53,6 +53,7 @@ module top_artya7 (
|
|||
.instr_rvalid_i (instr_rvalid),
|
||||
.instr_addr_o (instr_addr),
|
||||
.instr_rdata_i (instr_rdata),
|
||||
.instr_rdata_intg_i ('0),
|
||||
.instr_err_i ('b0),
|
||||
|
||||
.data_req_o (data_req),
|
||||
|
@ -62,7 +63,9 @@ module top_artya7 (
|
|||
.data_be_o (data_be),
|
||||
.data_addr_o (data_addr),
|
||||
.data_wdata_o (data_wdata),
|
||||
.data_wdata_intg_o (),
|
||||
.data_rdata_i (data_rdata),
|
||||
.data_rdata_intg_i ('0),
|
||||
.data_err_i ('b0),
|
||||
|
||||
.irq_software_i (1'b0),
|
||||
|
|
|
@ -195,6 +195,7 @@ module ibex_simple_system (
|
|||
.instr_rvalid_i (instr_rvalid),
|
||||
.instr_addr_o (instr_addr),
|
||||
.instr_rdata_i (instr_rdata),
|
||||
.instr_rdata_intg_i ('0),
|
||||
.instr_err_i (instr_err),
|
||||
|
||||
.data_req_o (host_req[CoreD]),
|
||||
|
@ -204,7 +205,9 @@ module ibex_simple_system (
|
|||
.data_be_o (host_be[CoreD]),
|
||||
.data_addr_o (host_addr[CoreD]),
|
||||
.data_wdata_o (host_wdata[CoreD]),
|
||||
.data_wdata_intg_o (),
|
||||
.data_rdata_i (host_rdata[CoreD]),
|
||||
.data_rdata_intg_i ('0),
|
||||
.data_err_i (host_err[CoreD]),
|
||||
|
||||
.irq_software_i (1'b0),
|
||||
|
|
|
@ -846,7 +846,6 @@ module ibex_core import ibex_pkg::*; #(
|
|||
assign rf_ecc_err_comb = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Crash dump output //
|
||||
///////////////////////
|
||||
|
|
|
@ -47,6 +47,7 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
input logic instr_rvalid_i,
|
||||
input logic [31:0] instr_addr_i,
|
||||
input logic [31:0] instr_rdata_i,
|
||||
input logic [6:0] instr_rdata_intg_i,
|
||||
input logic instr_err_i,
|
||||
|
||||
input logic data_req_i,
|
||||
|
@ -56,7 +57,9 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
input logic [3:0] data_be_i,
|
||||
input logic [31:0] data_addr_i,
|
||||
input logic [31:0] data_wdata_i,
|
||||
output logic [6:0] data_wdata_intg_o,
|
||||
input logic [31:0] data_rdata_i,
|
||||
input logic [6:0] data_rdata_intg_i,
|
||||
input logic data_err_i,
|
||||
|
||||
input logic dummy_instr_id_i,
|
||||
|
@ -156,6 +159,7 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
|
||||
delayed_inputs_t [LockstepOffset-1:0] shadow_inputs_q;
|
||||
delayed_inputs_t shadow_inputs_in;
|
||||
logic [6:0] instr_rdata_intg_q, data_rdata_intg_q;
|
||||
// Packed arrays must be dealt with separately
|
||||
logic [TagSizeECC-1:0] shadow_tag_rdata_q [IC_NUM_WAYS][LockstepOffset];
|
||||
logic [LineSizeECC-1:0] shadow_data_rdata_q [IC_NUM_WAYS][LockstepOffset];
|
||||
|
@ -182,12 +186,16 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
// Delay the inputs
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
instr_rdata_intg_q <= '0;
|
||||
data_rdata_intg_q <= '0;
|
||||
for (int unsigned i = 0; i < LockstepOffset; i++) begin
|
||||
shadow_inputs_q[i] <= delayed_inputs_t'('0);
|
||||
shadow_tag_rdata_q[i] <= '{default:0};
|
||||
shadow_data_rdata_q[i] <= '{default:0};
|
||||
end
|
||||
end else begin
|
||||
instr_rdata_intg_q <= instr_rdata_intg_i;
|
||||
data_rdata_intg_q <= data_rdata_intg_i;
|
||||
for (int unsigned i = 0; i < LockstepOffset-1; i++) begin
|
||||
shadow_inputs_q[i] <= shadow_inputs_q[i+1];
|
||||
shadow_tag_rdata_q[i] <= shadow_tag_rdata_q[i+1];
|
||||
|
@ -199,6 +207,38 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
end
|
||||
end
|
||||
|
||||
////////////////////////////
|
||||
// Bus integrity checking //
|
||||
////////////////////////////
|
||||
|
||||
logic bus_intg_err;
|
||||
logic [1:0] instr_intg_err, data_intg_err;
|
||||
logic [31:0] unused_wdata;
|
||||
|
||||
// Checks on incoming data
|
||||
prim_secded_39_32_dec u_instr_intg_dec (
|
||||
.data_i ({instr_rdata_intg_q, shadow_inputs_q[LockstepOffset-1].instr_rdata}),
|
||||
.data_o (),
|
||||
.syndrome_o (),
|
||||
.err_o (instr_intg_err)
|
||||
);
|
||||
|
||||
prim_secded_39_32_dec u_data_intg_dec (
|
||||
.data_i ({data_rdata_intg_q, shadow_inputs_q[LockstepOffset-1].data_rdata}),
|
||||
.data_o (),
|
||||
.syndrome_o (),
|
||||
.err_o (data_intg_err)
|
||||
);
|
||||
|
||||
assign bus_intg_err = (shadow_inputs_q[LockstepOffset-1].instr_rvalid & |instr_intg_err) |
|
||||
(shadow_inputs_q[LockstepOffset-1].data_rvalid & |data_intg_err);
|
||||
|
||||
// Generate integrity bits
|
||||
prim_secded_39_32_enc u_data_gen (
|
||||
.data_i (data_wdata_i),
|
||||
.data_o ({data_wdata_intg_o, unused_wdata})
|
||||
);
|
||||
|
||||
///////////////////
|
||||
// Output delays //
|
||||
///////////////////
|
||||
|
@ -400,7 +440,7 @@ module ibex_lockstep import ibex_pkg::*; #(
|
|||
logic outputs_mismatch;
|
||||
|
||||
assign outputs_mismatch = enable_cmp_q & (shadow_outputs_q != core_outputs_q[0]);
|
||||
assign alert_major_o = outputs_mismatch | shadow_alert_major;
|
||||
assign alert_major_o = outputs_mismatch | shadow_alert_major | bus_intg_err;
|
||||
assign alert_minor_o = shadow_alert_minor;
|
||||
|
||||
endmodule
|
||||
|
|
126
rtl/ibex_top.sv
126
rtl/ibex_top.sv
|
@ -51,6 +51,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
input logic instr_rvalid_i,
|
||||
output logic [31:0] instr_addr_o,
|
||||
input logic [31:0] instr_rdata_i,
|
||||
input logic [6:0] instr_rdata_intg_i,
|
||||
input logic instr_err_i,
|
||||
|
||||
// Data memory interface
|
||||
|
@ -61,7 +62,9 @@ module ibex_top import ibex_pkg::*; #(
|
|||
output logic [3:0] data_be_o,
|
||||
output logic [31:0] data_addr_o,
|
||||
output logic [31:0] data_wdata_o,
|
||||
output logic [6:0] data_wdata_intg_o,
|
||||
input logic [31:0] data_rdata_i,
|
||||
input logic [6:0] data_rdata_intg_i,
|
||||
input logic data_err_i,
|
||||
|
||||
// Interrupt inputs
|
||||
|
@ -427,6 +430,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
instr_rvalid_i,
|
||||
instr_addr_o,
|
||||
instr_rdata_i,
|
||||
instr_rdata_intg_i,
|
||||
instr_err_i,
|
||||
data_req_o,
|
||||
data_gnt_i,
|
||||
|
@ -436,6 +440,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
data_addr_o,
|
||||
data_wdata_o,
|
||||
data_rdata_i,
|
||||
data_rdata_intg_i,
|
||||
data_err_i,
|
||||
dummy_instr_id,
|
||||
rf_raddr_a,
|
||||
|
@ -475,6 +480,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
logic instr_rvalid_local;
|
||||
logic [31:0] instr_addr_local;
|
||||
logic [31:0] instr_rdata_local;
|
||||
logic [6:0] instr_rdata_intg_local;
|
||||
logic instr_err_local;
|
||||
|
||||
logic data_req_local;
|
||||
|
@ -484,7 +490,9 @@ module ibex_top import ibex_pkg::*; #(
|
|||
logic [3:0] data_be_local;
|
||||
logic [31:0] data_addr_local;
|
||||
logic [31:0] data_wdata_local;
|
||||
logic [6:0] data_wdata_intg_local;
|
||||
logic [31:0] data_rdata_local;
|
||||
logic [6:0] data_rdata_intg_local;
|
||||
logic data_err_local;
|
||||
|
||||
logic dummy_instr_id_local;
|
||||
|
@ -526,6 +534,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
instr_rvalid_i,
|
||||
instr_addr_o,
|
||||
instr_rdata_i,
|
||||
instr_rdata_intg_i,
|
||||
instr_err_i,
|
||||
data_req_o,
|
||||
data_gnt_i,
|
||||
|
@ -535,6 +544,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
data_addr_o,
|
||||
data_wdata_o,
|
||||
data_rdata_i,
|
||||
data_rdata_intg_i,
|
||||
data_err_i,
|
||||
dummy_instr_id,
|
||||
rf_raddr_a,
|
||||
|
@ -572,6 +582,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
instr_rvalid_local,
|
||||
instr_addr_local,
|
||||
instr_rdata_local,
|
||||
instr_rdata_intg_local,
|
||||
instr_err_local,
|
||||
data_req_local,
|
||||
data_gnt_local,
|
||||
|
@ -581,6 +592,7 @@ module ibex_top import ibex_pkg::*; #(
|
|||
data_addr_local,
|
||||
data_wdata_local,
|
||||
data_rdata_local,
|
||||
data_rdata_intg_local,
|
||||
data_err_local,
|
||||
dummy_instr_id_local,
|
||||
rf_raddr_a_local,
|
||||
|
@ -659,68 +671,76 @@ module ibex_top import ibex_pkg::*; #(
|
|||
.DmHaltAddr ( DmHaltAddr ),
|
||||
.DmExceptionAddr ( DmExceptionAddr )
|
||||
) u_ibex_lockstep (
|
||||
.clk_i (clk),
|
||||
.rst_ni (rst_ni),
|
||||
.clk_i (clk),
|
||||
.rst_ni (rst_ni),
|
||||
|
||||
.hart_id_i (hart_id_local),
|
||||
.boot_addr_i (boot_addr_local),
|
||||
.hart_id_i (hart_id_local),
|
||||
.boot_addr_i (boot_addr_local),
|
||||
|
||||
.instr_req_i (instr_req_local),
|
||||
.instr_gnt_i (instr_gnt_local),
|
||||
.instr_rvalid_i (instr_rvalid_local),
|
||||
.instr_addr_i (instr_addr_local),
|
||||
.instr_rdata_i (instr_rdata_local),
|
||||
.instr_err_i (instr_err_local),
|
||||
.instr_req_i (instr_req_local),
|
||||
.instr_gnt_i (instr_gnt_local),
|
||||
.instr_rvalid_i (instr_rvalid_local),
|
||||
.instr_addr_i (instr_addr_local),
|
||||
.instr_rdata_i (instr_rdata_local),
|
||||
.instr_rdata_intg_i (instr_rdata_intg_local),
|
||||
.instr_err_i (instr_err_local),
|
||||
|
||||
.data_req_i (data_req_local),
|
||||
.data_gnt_i (data_gnt_local),
|
||||
.data_rvalid_i (data_rvalid_local),
|
||||
.data_we_i (data_we_local),
|
||||
.data_be_i (data_be_local),
|
||||
.data_addr_i (data_addr_local),
|
||||
.data_wdata_i (data_wdata_local),
|
||||
.data_rdata_i (data_rdata_local),
|
||||
.data_err_i (data_err_local),
|
||||
.data_req_i (data_req_local),
|
||||
.data_gnt_i (data_gnt_local),
|
||||
.data_rvalid_i (data_rvalid_local),
|
||||
.data_we_i (data_we_local),
|
||||
.data_be_i (data_be_local),
|
||||
.data_addr_i (data_addr_local),
|
||||
.data_wdata_i (data_wdata_local),
|
||||
.data_wdata_intg_o (data_wdata_intg_local),
|
||||
.data_rdata_i (data_rdata_local),
|
||||
.data_rdata_intg_i (data_rdata_intg_local),
|
||||
.data_err_i (data_err_local),
|
||||
|
||||
.dummy_instr_id_i (dummy_instr_id_local),
|
||||
.rf_raddr_a_i (rf_raddr_a_local),
|
||||
.rf_raddr_b_i (rf_raddr_b_local),
|
||||
.rf_waddr_wb_i (rf_waddr_wb_local),
|
||||
.rf_we_wb_i (rf_we_wb_local),
|
||||
.rf_wdata_wb_ecc_i (rf_wdata_wb_ecc_local),
|
||||
.rf_rdata_a_ecc_i (rf_rdata_a_ecc_local),
|
||||
.rf_rdata_b_ecc_i (rf_rdata_b_ecc_local),
|
||||
.dummy_instr_id_i (dummy_instr_id_local),
|
||||
.rf_raddr_a_i (rf_raddr_a_local),
|
||||
.rf_raddr_b_i (rf_raddr_b_local),
|
||||
.rf_waddr_wb_i (rf_waddr_wb_local),
|
||||
.rf_we_wb_i (rf_we_wb_local),
|
||||
.rf_wdata_wb_ecc_i (rf_wdata_wb_ecc_local),
|
||||
.rf_rdata_a_ecc_i (rf_rdata_a_ecc_local),
|
||||
.rf_rdata_b_ecc_i (rf_rdata_b_ecc_local),
|
||||
|
||||
.ic_tag_req_i (ic_tag_req_local),
|
||||
.ic_tag_write_i (ic_tag_write_local),
|
||||
.ic_tag_addr_i (ic_tag_addr_local),
|
||||
.ic_tag_wdata_i (ic_tag_wdata_local),
|
||||
.ic_tag_rdata_i (ic_tag_rdata_local),
|
||||
.ic_data_req_i (ic_data_req_local),
|
||||
.ic_data_write_i (ic_data_write_local),
|
||||
.ic_data_addr_i (ic_data_addr_local),
|
||||
.ic_data_wdata_i (ic_data_wdata_local),
|
||||
.ic_data_rdata_i (ic_data_rdata_local),
|
||||
.ic_tag_req_i (ic_tag_req_local),
|
||||
.ic_tag_write_i (ic_tag_write_local),
|
||||
.ic_tag_addr_i (ic_tag_addr_local),
|
||||
.ic_tag_wdata_i (ic_tag_wdata_local),
|
||||
.ic_tag_rdata_i (ic_tag_rdata_local),
|
||||
.ic_data_req_i (ic_data_req_local),
|
||||
.ic_data_write_i (ic_data_write_local),
|
||||
.ic_data_addr_i (ic_data_addr_local),
|
||||
.ic_data_wdata_i (ic_data_wdata_local),
|
||||
.ic_data_rdata_i (ic_data_rdata_local),
|
||||
|
||||
.irq_software_i (irq_software_local),
|
||||
.irq_timer_i (irq_timer_local),
|
||||
.irq_external_i (irq_external_local),
|
||||
.irq_fast_i (irq_fast_local),
|
||||
.irq_nm_i (irq_nm_local),
|
||||
.irq_pending_i (irq_pending_local),
|
||||
.irq_software_i (irq_software_local),
|
||||
.irq_timer_i (irq_timer_local),
|
||||
.irq_external_i (irq_external_local),
|
||||
.irq_fast_i (irq_fast_local),
|
||||
.irq_nm_i (irq_nm_local),
|
||||
.irq_pending_i (irq_pending_local),
|
||||
|
||||
.debug_req_i (debug_req_local),
|
||||
.crash_dump_i (crash_dump_local),
|
||||
.debug_req_i (debug_req_local),
|
||||
.crash_dump_i (crash_dump_local),
|
||||
|
||||
.fetch_enable_i (fetch_enable_local),
|
||||
.alert_minor_o (lockstep_alert_minor_local),
|
||||
.alert_major_o (lockstep_alert_major_local),
|
||||
.core_busy_i (core_busy_local),
|
||||
.test_en_i (test_en_i),
|
||||
.scan_rst_ni (scan_rst_ni)
|
||||
.fetch_enable_i (fetch_enable_local),
|
||||
.alert_minor_o (lockstep_alert_minor_local),
|
||||
.alert_major_o (lockstep_alert_major_local),
|
||||
.core_busy_i (core_busy_local),
|
||||
.test_en_i (test_en_i),
|
||||
.scan_rst_ni (scan_rst_ni)
|
||||
);
|
||||
|
||||
// Manually buffer the output signals.
|
||||
prim_buf #(.Width (7)) u_prim_buf_wdata_intg (
|
||||
.in_i(data_wdata_intg_local),
|
||||
.out_o(data_wdata_intg_o)
|
||||
);
|
||||
|
||||
prim_buf u_prim_buf_alert_minor (
|
||||
.in_i(lockstep_alert_minor_local),
|
||||
.out_o(lockstep_alert_minor)
|
||||
|
@ -734,8 +754,10 @@ module ibex_top import ibex_pkg::*; #(
|
|||
end else begin : gen_no_lockstep
|
||||
assign lockstep_alert_major = 1'b0;
|
||||
assign lockstep_alert_minor = 1'b0;
|
||||
logic unused_scan;
|
||||
assign data_wdata_intg_o = 'b0;
|
||||
logic unused_scan, unused_intg;
|
||||
assign unused_scan = scan_rst_ni;
|
||||
assign unused_intg = |{instr_rdata_intg_i, data_rdata_intg_i};
|
||||
end
|
||||
|
||||
assign alert_major_o = core_alert_major | lockstep_alert_major;
|
||||
|
|
|
@ -47,6 +47,7 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
input logic instr_rvalid_i,
|
||||
output logic [31:0] instr_addr_o,
|
||||
input logic [31:0] instr_rdata_i,
|
||||
input logic [6:0] instr_rdata_intg_i,
|
||||
input logic instr_err_i,
|
||||
|
||||
// Data memory interface
|
||||
|
@ -57,7 +58,9 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
output logic [3:0] data_be_o,
|
||||
output logic [31:0] data_addr_o,
|
||||
output logic [31:0] data_wdata_o,
|
||||
output logic [6:0] data_wdata_intg_o,
|
||||
input logic [31:0] data_rdata_i,
|
||||
input logic [6:0] data_rdata_intg_i,
|
||||
input logic data_err_i,
|
||||
|
||||
// Interrupt inputs
|
||||
|
@ -144,6 +147,7 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
.instr_rvalid_i,
|
||||
.instr_addr_o,
|
||||
.instr_rdata_i,
|
||||
.instr_rdata_intg_i,
|
||||
.instr_err_i,
|
||||
|
||||
.data_req_o,
|
||||
|
@ -153,7 +157,9 @@ module ibex_top_tracing import ibex_pkg::*; #(
|
|||
.data_be_o,
|
||||
.data_addr_o,
|
||||
.data_wdata_o,
|
||||
.data_wdata_intg_o,
|
||||
.data_rdata_i,
|
||||
.data_rdata_intg_i,
|
||||
.data_err_i,
|
||||
|
||||
.irq_software_i,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue