From bf48bb80132cb7daa1f70a0ff93ffb688ca3dc70 Mon Sep 17 00:00:00 2001 From: Maurus Item <itemm@student.ethz.ch> Date: Wed, 3 Jul 2024 11:45:20 +0200 Subject: [PATCH] Added different types of HCI copies. --- rtl/common/hci_package.sv | 7 +++ rtl/parity/hci_copy_sink.sv | 68 +++++++++++++++++++------- rtl/parity/hci_copy_source.sv | 89 ++++++++++++++++++++++++----------- 3 files changed, 121 insertions(+), 43 deletions(-) diff --git a/rtl/common/hci_package.sv b/rtl/common/hci_package.sv index 35e87d9..8ab9da3 100644 --- a/rtl/common/hci_package.sv +++ b/rtl/common/hci_package.sv @@ -64,4 +64,11 @@ package hci_package; STREAMER_IDLE, STREAMER_WORKING, STREAMER_DONE } hci_streamer_state_t; + typedef enum { + COPY, // Full copy and comparison of all signals + NO_ECC, // Do not assign and compare ecc signals + NO_DATA, // Do not assign and compare data signals + CTRL_ONLY, // Do not assign either ecc nor data signals + } hci_copy_t; + endpackage // hci_package diff --git a/rtl/parity/hci_copy_sink.sv b/rtl/parity/hci_copy_sink.sv index 6a7de19..29378b8 100644 --- a/rtl/parity/hci_copy_sink.sv +++ b/rtl/parity/hci_copy_sink.sv @@ -18,50 +18,86 @@ * stream `tcdm_main` and compare it with a copy stream `tcdm_copy` element. * Together with hci_copy_sink this allows for fault detection on a chain of * HCI modules. + * + * How "deep" the copy is can be set with the parameter COPY_TYPE. + * COPY_TYPE MUST match on connected sinks and sources! + * + * The available options are: + * - COPY: Fully copy of everything. + * - NO_ECC: No copy of ECC signals. + * - NO_DATA: No copy of data signals. + * - CTRL_ONLY: o copy of data or ECC signals. */ `include "hci_helpers.svh" module hci_copy_sink - import hci_package::*; -( + import hci_package::*; +#( + parameter hci_package::hci_copy_t COPY_TYPE = COPY +) ( input logic clk_i, input logic rst_ni, hci_core_intf.monitor tcdm_main, hci_core_intf.target tcdm_copy, - output logic fault_detected_o + output logic fault_o ); + + logic fault, ctrl_fault, data_fault, ecc_fault; + + // Control signals always assigned assign tcdm_copy.gnt = tcdm_main.gnt; - assign tcdm_copy.r_data = tcdm_main.r_data; assign tcdm_copy.r_valid = tcdm_main.r_valid; assign tcdm_copy.r_user = tcdm_main.r_user; assign tcdm_copy.r_id = tcdm_main.r_id; assign tcdm_copy.r_opc = tcdm_main.r_opc; - assign tcdm_copy.egnt = tcdm_main.egnt; - assign tcdm_copy.r_evalid = tcdm_main.r_evalid; - assign tcdm_copy.r_ecc = tcdm_main.r_ecc; - // Compare Signals - logic fault_detected; - assign fault_detected = + assign ctrl_fault = ( tcdm_main.req != tcdm_copy.req ) | - ( tcdm_main.ereq != tcdm_copy.ereq ) | - ( tcdm_main.r_eready != tcdm_copy.r_eready ) | - ( tcdm_main.ecc != tcdm_copy.ecc ) | ( tcdm_main.add != tcdm_copy.add ) | ( tcdm_main.wen != tcdm_copy.wen ) | - ( tcdm_main.data != tcdm_copy.data ) | ( tcdm_main.be != tcdm_copy.be ) | ( tcdm_main.r_ready != tcdm_copy.r_ready ) | ( tcdm_main.user != tcdm_copy.user ) | ( tcdm_main.id != tcdm_copy.id ); + + // Data + if (COPY_TYPE == NO_DATA || COPY_TYPE = CTRL_ONLY) begin + assign data_fault = 1'b0; + end + else + assign data_fault = tcdm_main.data != tcdm_copy.data + assign tcdm_copy.r_data = tcdm_main.r_data; + begin + + + // ECC + if (COPY_TYPE == NO_ECC || COPY_TYPE = CTRL_ONLY) begin + assign ecc_fault = 1'b0; + end + else + assign tcdm_copy.egnt = tcdm_main.egnt; + assign tcdm_copy.r_evalid = tcdm_main.r_evalid; + assign tcdm_copy.r_ecc = tcdm_main.r_ecc; + + assign ecc_fault = + ( tcdm_main.req != tcdm_copy.req ) | + ( tcdm_main.ereq != tcdm_copy.ereq ) | + ( tcdm_main.r_eready != tcdm_copy.r_eready ) | + ( tcdm_main.ecc != tcdm_copy.ecc ) | + begin + + + assign fault = ctrl_fault | data_fault | ecc_fault; + + // Store in FF so critical path is broken always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin - fault_detected_o <= '0; + fault_o <= '0; end else begin - fault_detected_o <= fault_detected; + fault_o <= fault; end end diff --git a/rtl/parity/hci_copy_source.sv b/rtl/parity/hci_copy_source.sv index 564c7dc..9664c52 100644 --- a/rtl/parity/hci_copy_source.sv +++ b/rtl/parity/hci_copy_source.sv @@ -18,50 +18,85 @@ * stream `tcdm_main` and copy it to an output hci interface `tcdm_copy`. * Together with hci_copy_sink this allows for fault detection on a chain of * HCI modules. + * + * How "deep" the copy is can be set with the parameter COPY_TYPE. + * COPY_TYPE MUST match on connected sinks and sources! + * + * The available options are: + * - COPY: Fully copy of everything. + * - NO_ECC: No copy of ECC signals. + * - NO_DATA: No copy of data signals. + * - CTRL_ONLY: o copy of data or ECC signals. */ - `include "hci_helpers.svh" module hci_copy_source import hci_package::*; -( +#( + parameter hci_package::hci_copy_t COPY_TYPE = COPY +) ( input logic clk_i, input logic rst_ni, hci_core_intf.monitor tcdm_main, hci_core_intf.initiator tcdm_copy, - output logic fault_detected_o + output logic fault_o ); + + logic fault, ctrl_fault, data_fault, ecc_fault; + + // Control signals always assigned + assign tcdm_main.req = tcdm_copy.req; + assign tcdm_main.add = tcdm_copy.add; + assign tcdm_main.wen = tcdm_copy.wen; + assign tcdm_main.be = tcdm_copy.be; + assign tcdm_main.r_ready = tcdm_copy.r_ready; + assign tcdm_main.user = tcdm_copy.user; + assign tcdm_main.id = tcdm_copy.id; + + assign ctrl_fault = + ( tcdm_copy.gnt != tcdm_main.gnt ) | + ( tcdm_copy.r_valid != tcdm_main.r_valid ) | + ( tcdm_copy.r_user != tcdm_main.r_user ) | + ( tcdm_copy.r_id != tcdm_main.r_id ) | + ( tcdm_copy.r_opc != tcdm_main.r_opc ); + + + // Data + if (COPY_TYPE == NO_DATA || COPY_TYPE = CTRL_ONLY) begin + assign data_fault = 1'b0; + end + else + assign data_fault = tcdm_main.r_data != tcdm_copy.r_data + assign tcdm_copy.data = tcdm_main.data; + begin + + + // ECC + if (COPY_TYPE == NO_ECC || COPY_TYPE = CTRL_ONLY) begin + assign ecc_fault = 1'b0; + end + else + assign tcdm_main.req = tcdm_copy.req; + assign tcdm_main.ereq = tcdm_copy.ereq; + assign tcdm_main.r_eready = tcdm_copy.r_eready; + assign tcdm_main.ecc = tcdm_copy.ecc; + + assign ecc_fault = + ( tcdm_copy.egnt != tcdm_main.egnt ) | + ( tcdm_copy.r_evalid != tcdm_main.r_evalid ) | + ( tcdm_copy.r_ecc != tcdm_main.r_ecc ); + begin - assign tcdm_copy.req = tcdm_main.req; - assign tcdm_copy.ereq = tcdm_main.ereq; - assign tcdm_copy.r_eready = tcdm_main.r_eready; - assign tcdm_copy.ecc = tcdm_main.ecc; - assign tcdm_copy.add = tcdm_main.add; - assign tcdm_copy.wen = tcdm_main.wen; - assign tcdm_copy.data = tcdm_main.data; - assign tcdm_copy.be = tcdm_main.be; - assign tcdm_copy.r_ready = tcdm_main.r_ready; - assign tcdm_copy.user = tcdm_main.user; - assign tcdm_copy.id = tcdm_main.id; - // Compare Signals - assign fault_detected = - ( tcdm_copy.gnt != tcdm_main.gnt ) | - ( tcdm_copy.r_data != tcdm_main.r_data ) | - ( tcdm_copy.r_valid != tcdm_main.r_valid ) | - ( tcdm_copy.r_user != tcdm_main.r_user ) | - ( tcdm_copy.r_id != tcdm_main.r_id ) | - ( tcdm_copy.r_opc != tcdm_main.r_opc ) | - ( tcdm_copy.egnt != tcdm_main.egnt ) | - ( tcdm_copy.r_evalid != tcdm_main.r_evalid ) | - ( tcdm_copy.r_ecc != tcdm_main.r_ecc ); + assign fault = ctrl_fault | data_fault | ecc_fault; + // Store in FF so critical path is broken always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin - fault_detected_o <= '0; + fault_o <= '0; end else begin - fault_detected_o <= fault_detected; + fault_o <= fault; end end