From 846a7e70ab9447b3f5952dcfa35e58993c6d790e Mon Sep 17 00:00:00 2001 From: Maurus Item Date: Fri, 21 Jun 2024 10:38:29 +0200 Subject: [PATCH 1/3] Added regfile parity checker. --- Bender.yml | 1 + rtl/hwpe_ctrl_regfile_parity.sv | 67 +++++++++++++++++++++++++++++++++ src_files.yml | 1 + 3 files changed, 69 insertions(+) create mode 100644 rtl/hwpe_ctrl_regfile_parity.sv diff --git a/Bender.yml b/Bender.yml index dbc1498..827c671 100644 --- a/Bender.yml +++ b/Bender.yml @@ -19,6 +19,7 @@ sources: # Level 1 - rtl/hwpe_ctrl_regfile_ff.sv - rtl/hwpe_ctrl_regfile_latch.sv + - rtl/hwpe_ctrl_regfile_parity.sv - rtl/hwpe_ctrl_seq_mult.sv - rtl/hwpe_ctrl_uloop.sv # Level 2 diff --git a/rtl/hwpe_ctrl_regfile_parity.sv b/rtl/hwpe_ctrl_regfile_parity.sv new file mode 100644 index 0000000..45817aa --- /dev/null +++ b/rtl/hwpe_ctrl_regfile_parity.sv @@ -0,0 +1,67 @@ +/* + * hwpe_ctrl_regfile_parity.sv + * Maurus Item + * + * Copyright (C) 2024 ETH Zurich, University of Bologna + * Copyright and related rights are licensed under the Solderpad Hardware + * License, Version 0.51 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law + * or agreed to in writing, software, hardware and materials distributed under + * this 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. + * + * Module that checks for even parity on a regfile, output delayed to not end up in critcal path. + */ + +module hwpe_ctrl_regfile_parity + import hwpe_ctrl_package::*; +#( + int unsigned N_IO_REGS, + int unsigned N_GENERIC_REGS +)( + input logic clk_i, + input logic rst_ni, + input hwpe_ctrl_package::ctrl_regfile_t reg_file_i, + output logic fault_detected_o +); + + // Build an even XOR tree per register + parameter int XOR_INPUTS = N_IO_REGS + N_GENERIC_REGS + 1; + parameter int XOR_OPS = XOR_INPUTS - 1; // Always one less than inputs e.g. x + y -> 2 Addends 1 Addition + parameter int TREE_NODES = XOR_OPS + XOR_INPUTS; + + // Array of addresses for tree adder + logic [TREE_NODES-1:0][31:0] xor_intermediate; + + // Assign Input Nodes + for (genvar i = 0; i < N_IO_REGS; i++) begin: gen_hwpe_params_assign + assign xor_intermediate[XOR_OPS + i] = reg_file_i.hwpe_params[i]; + end + + for (genvar i = 0; i < N_GENERIC_REGS ; i++) begin: gen_generic_params_assign + assign xor_intermediate[XOR_OPS + N_IO_REGS + i] = reg_file_i.generic_params[i]; + end + + assign xor_intermediate[XOR_OPS + N_IO_REGS + N_GENERIC_REGS] = reg_file_i.ext_data; + + // Calculate XOR in a Tree + for (genvar i = 0; i < XOR_OPS; i++) + begin: gen_adder_tree + assign xor_intermediate[i] = xor_intermediate[i * 2 + 1] ^ xor_intermediate[i * 2 + 2]; + end + + // Take output of tree and OR Bits -> One register should be set in a way so each bit XORs to 0. + logic fault_detected; + assign fault_detected = |xor_intermediate[0]; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (!rst_ni) begin + fault_detected_o <= '0; + end else begin + fault_detected_o <= fault_detected; + end + end + +endmodule: hwpe_ctrl_regfile_parity diff --git a/src_files.yml b/src_files.yml index dcc7571..b248d89 100644 --- a/src_files.yml +++ b/src_files.yml @@ -11,6 +11,7 @@ hwpe-ctrl: rtl/hwpe_ctrl_regfile.sv, rtl/hwpe_ctrl_regfile_latch.sv, rtl/hwpe_ctrl_regfile_latch_test_wrap.sv, + rtl/hwpe_ctrl_regfile_parity.sv, rtl/hwpe_ctrl_slave.sv, rtl/hwpe_ctrl_seq_mult.sv, rtl/hwpe_ctrl_uloop.sv, From a60a313715498d9542c2370ad7c18acdadc207b3 Mon Sep 17 00:00:00 2001 From: Maurus Item Date: Mon, 24 Jun 2024 17:59:14 +0200 Subject: [PATCH 2/3] Combined upper and lower 16 bits and added documentation. --- rtl/hwpe_ctrl_regfile_parity.sv | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/rtl/hwpe_ctrl_regfile_parity.sv b/rtl/hwpe_ctrl_regfile_parity.sv index 45817aa..fa71672 100644 --- a/rtl/hwpe_ctrl_regfile_parity.sv +++ b/rtl/hwpe_ctrl_regfile_parity.sv @@ -12,7 +12,34 @@ * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * - * Module that checks for even parity on a regfile, output delayed to not end up in critcal path. + * Module that checks for *almost bitwise even parity on a regfile, output delayed to not end up in critcal path. + * + * You should have one dedicated "parity register", to use this module + * |=======================================================================| + * || # reg | offset | bits | bitmask || content || + * ||-------+----------+---------+--------------++------------------------|| + * ||-------+----------+---------+--------------++------------------------|| + * || ANY | ANY | | || PARITY_REGISTER: || + * || | | 31:16 | 0xFFFF0000 || PARITY_INFORMATION || + * || | | 15: 0 | 0x0000FFFF || XOR_SIGNATURE || + * |=======================================================================| + * + * The signature has the following format + * XOR_SIGNATURE = PARITY_INFORMATION ^ REGISTER_1[15:0] ^ REGISTER_1[31:16] ^ REGISTER_2[15:0] ^ REGISTER_2[31:16] ... + * + * You can use the following c-code to calculate it: + * + * uint_32t parity_register; // Final value in register + * uint_16t parity_info; // Your additional info in here + * + * // Collect all other registers + * uint_32t xor_signature = 0; // Temp variable to collect all parity info + * xor_signature ^= register_1; + * xor_signature ^= register_2; + * .... + * + * parity_register = (xor_signature ^ ((xor_signature ^ parity_info) << 16)) & 0xFF00 | parity_info & 0x00FF + * */ module hwpe_ctrl_regfile_parity @@ -54,7 +81,7 @@ module hwpe_ctrl_regfile_parity // Take output of tree and OR Bits -> One register should be set in a way so each bit XORs to 0. logic fault_detected; - assign fault_detected = |xor_intermediate[0]; + assign fault_detected = |(xor_intermediate[0][31:16] ^ xor_intermediate[0][15:0]); always_ff @(posedge clk_i or negedge rst_ni) begin if (!rst_ni) begin From 3d12ddb68c06124350828494ef9d17c762c69c81 Mon Sep 17 00:00:00 2001 From: Maurus Item Date: Thu, 27 Jun 2024 09:26:10 +0200 Subject: [PATCH 3/3] Improved regfile parity module documentation. --- rtl/hwpe_ctrl_regfile_parity.sv | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/rtl/hwpe_ctrl_regfile_parity.sv b/rtl/hwpe_ctrl_regfile_parity.sv index fa71672..51a79d5 100644 --- a/rtl/hwpe_ctrl_regfile_parity.sv +++ b/rtl/hwpe_ctrl_regfile_parity.sv @@ -12,9 +12,14 @@ * CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. * - * Module that checks for *almost bitwise even parity on a regfile, output delayed to not end up in critcal path. + * Module that checks for bitwise even parity on a regfile for all dwords. + * Output delayed to not end up in critcal path. + * + * You should have one dedicated "parity register", to use this module where + * you place a XOR Signature dword (16 bits) to achieve parity. Where in the + * register file this is is up to your implementation. You can use the other + * half for something else, sensible would be additional parity information. * - * You should have one dedicated "parity register", to use this module * |=======================================================================| * || # reg | offset | bits | bitmask || content || * ||-------+----------+---------+--------------++------------------------|| @@ -24,7 +29,7 @@ * || | | 15: 0 | 0x0000FFFF || XOR_SIGNATURE || * |=======================================================================| * - * The signature has the following format + * The signature should be the XOR of all dwords in the regfile e.g.: * XOR_SIGNATURE = PARITY_INFORMATION ^ REGISTER_1[15:0] ^ REGISTER_1[31:16] ^ REGISTER_2[15:0] ^ REGISTER_2[31:16] ... * * You can use the following c-code to calculate it: @@ -38,7 +43,7 @@ * xor_signature ^= register_2; * .... * - * parity_register = (xor_signature ^ ((xor_signature ^ parity_info) << 16)) & 0xFF00 | parity_info & 0x00FF + * parity_register = (xor_signature ^ ((xor_signature ^ parity_info) << 16)) & 0xFFFF0000 | parity_info & 0x0000FFFF * */